blob: d58ad5a78472a5eae6d7426db141f1b5e7f11a8e [file] [log] [blame]
Karl Schimpf2e7daef2015-01-09 13:04:13 -08001//===- unittest/IceParseInstsTest.cpp - test instruction errors -----------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
John Porto8eefffa2015-06-11 15:14:37 -070010#include <string>
11
Jim Stichnoth98da9662015-06-27 06:38:08 -070012#pragma clang diagnostic push
13#pragma clang diagnostic ignored "-Wunused-parameter"
Karl Schimpf2e7daef2015-01-09 13:04:13 -080014#include "llvm/ADT/STLExtras.h"
15#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
16#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070017#pragma clang diagnostic pop
Karl Schimpf2e7daef2015-01-09 13:04:13 -080018
19#include "BitcodeMunge.h"
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -070020#include "unittests/Bitcode/NaClMungeTest.h"
Karl Schimpf2e7daef2015-01-09 13:04:13 -080021
22using namespace llvm;
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -070023using namespace naclmungetest;
Karl Schimpf2e7daef2015-01-09 13:04:13 -080024
25namespace {
26
John Porto8eefffa2015-06-11 15:14:37 -070027// The ParseError constant is passed to the BitcodeMunger to prevent translation
28// when we expect a Parse error.
29constexpr bool ParseError = true;
30
Karl Schimpfaf238b22015-01-20 12:19:15 -080031// Note: alignment stored as 0 or log2(Alignment)+1.
32uint64_t getEncAlignPower(unsigned Power) {
33 return Power + 1;
34}
35uint64_t getEncAlignZero() { return 0; }
36
Karl Schimpf2e7daef2015-01-09 13:04:13 -080037/// Test how we report a call arg that refers to nonexistent call argument
38TEST(IceParseInstsTest, NonexistentCallArg) {
39 const uint64_t BitcodeRecords[] = {
40 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
41 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator,
42 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator,
43 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator,
44 3, naclbitc::TYPE_CODE_VOID, Terminator,
45 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator,
46 0, naclbitc::BLK_CODE_EXIT, Terminator,
47 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 1, 0, Terminator,
48 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator,
49 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
50 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
Jim Stichnothdd842db2015-01-27 12:53:53 -080051 // Note: 100 is a bad value index in next line.
Karl Schimpf2e7daef2015-01-09 13:04:13 -080052 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator,
53 3, naclbitc::FUNC_CODE_INST_RET, Terminator,
54 0, naclbitc::BLK_CODE_EXIT, Terminator,
55 0, naclbitc::BLK_CODE_EXIT, Terminator
56 };
57
Karl Schimpf2e7daef2015-01-09 13:04:13 -080058 // Show bitcode objdump for BitcodeRecords.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -070059 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
60 EXPECT_FALSE(DumpMunger.runTest());
Karl Schimpf22ed4eb2015-03-04 12:17:20 -080061 EXPECT_EQ(" 66:4| 3: <34, 0, 4, 2, 100> | call void @f0(i32 "
62 "%p0, i32 @f0);\n"
63 "Error(66:4): Invalid relative value id: 100 (Must be <= 4)\n",
64 DumpMunger.getLinesWithSubstring("66:4"));
Karl Schimpf2e7daef2015-01-09 13:04:13 -080065
66 // Show that we get appropriate error when parsing in Subzero.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -070067 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
John Porto8eefffa2015-06-11 15:14:37 -070068 EXPECT_FALSE(Munger.runTest(ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -080069 EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n",
Jim Stichnothdd842db2015-01-27 12:53:53 -080070 Munger.getTestResults());
Karl Schimpfd8b32892015-04-16 15:47:25 -070071
72 // Show that we generate a fatal error when not allowing error recovery.
73 Munger.Flags.setAllowErrorRecovery(false);
John Porto8eefffa2015-06-11 15:14:37 -070074 EXPECT_DEATH(Munger.runTest(ParseError), ".*ERROR: Unable to continue.*");
Karl Schimpf2e7daef2015-01-09 13:04:13 -080075}
76
Karl Schimpfaf238b22015-01-20 12:19:15 -080077/// Test how we recognize alignments in alloca instructions.
78TEST(IceParseInstsTests, AllocaAlignment) {
79 const uint64_t BitcodeRecords[] = {
80 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
81 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator,
82 3, naclbitc::TYPE_CODE_NUMENTRY, 4, Terminator,
83 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator,
84 3, naclbitc::TYPE_CODE_VOID, Terminator,
85 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, Terminator,
86 3, naclbitc::TYPE_CODE_INTEGER, 8, Terminator,
87 0, naclbitc::BLK_CODE_EXIT, Terminator,
88 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator,
89 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
90 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
91 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(0), Terminator,
92 3, naclbitc::FUNC_CODE_INST_RET, Terminator,
93 0, naclbitc::BLK_CODE_EXIT, Terminator,
94 0, naclbitc::BLK_CODE_EXIT, Terminator};
95
96 const uint64_t ReplaceIndex = 11; // index for FUNC_CODE_INST_ALLOCA
97
98 // Show text when alignment is 1.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -070099 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
100 EXPECT_TRUE(DumpMunger.runTest());
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800101 EXPECT_EQ(" 62:4| 3: <19, 1, 1> | %v0 = alloca i8, i32 "
102 "%p0, align 1;\n",
103 DumpMunger.getLinesWithSubstring("62:4"));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800104
105 // Show that we can handle alignment of 1.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700106 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
107 EXPECT_TRUE(Munger.runTest());
Karl Schimpfaf238b22015-01-20 12:19:15 -0800108
109 // Show what happens when changing alignment to 0.
110 const uint64_t Align0[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700111 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800112 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignZero(), Terminator,
113 };
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700114 EXPECT_TRUE(Munger.runTest(ARRAY(Align0)));
115 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800116 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n",
117 DumpMunger.getLinesWithSubstring("alloca"));
118
119 // Show what happens when changing alignment to 2**30.
120 const uint64_t Align30[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700121 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800122 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(30), Terminator,
123 };
John Porto8eefffa2015-06-11 15:14:37 -0700124 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800125 EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800126 Munger.getTestResults());
127
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700128 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800129 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n",
130 DumpMunger.getLinesWithSubstring("alloca"));
131 EXPECT_EQ(
132 "Error(62:4): Alignment can't be greater than 2**29. Found: 2**30\n",
133 DumpMunger.getLinesWithSubstring("Error"));
134
135 // Show what happens when changing alignment to 2**29.
136 const uint64_t Align29[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700137 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800138 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(29), Terminator,
139 };
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700140 EXPECT_TRUE(Munger.runTest(ARRAY(Align29)));
141 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800142 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 536870912;\n",
143 DumpMunger.getLinesWithSubstring("alloca"));
144}
145
146// Test how we recognize alignments in load i32 instructions.
147TEST(IceParseInstsTests, LoadI32Alignment) {
148 const uint64_t BitcodeRecords[] = {
149 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
150 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator,
151 3, naclbitc::TYPE_CODE_NUMENTRY, 2, Terminator,
152 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator,
153 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 0, Terminator,
154 0, naclbitc::BLK_CODE_EXIT, Terminator,
155 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator,
156 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
157 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
158 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator,
159 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator,
160 0, naclbitc::BLK_CODE_EXIT, Terminator,
161 0, naclbitc::BLK_CODE_EXIT, Terminator};
162
163 const uint64_t ReplaceIndex = 9; // index for FUNC_CODE_INST_LOAD
164
165 // Show text when alignment is 1.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700166 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
167 EXPECT_TRUE(DumpMunger.runTest());
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800168 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load i32* %p0, "
169 "align 1;\n",
170 DumpMunger.getLinesWithSubstring("58:4"));
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700171 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
172 EXPECT_TRUE(Munger.runTest());
Karl Schimpfaf238b22015-01-20 12:19:15 -0800173
174 // Show what happens when changing alignment to 0.
175 const uint64_t Align0[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700176 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800177 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator,
178 };
John Porto8eefffa2015-06-11 15:14:37 -0700179 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800180 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800181 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700182 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800183 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n"
184 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
185 DumpMunger.getLinesWithSubstring("load"));
186
187 // Show what happens when changing alignment to 4.
188 const uint64_t Align4[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700189 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800190 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator,
191 };
John Porto8eefffa2015-06-11 15:14:37 -0700192 EXPECT_FALSE(Munger.runTest(ARRAY(Align4), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800193 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800194 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700195 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800196 EXPECT_EQ(" %v0 = load i32* %p0, align 4;\n"
197 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
198 DumpMunger.getLinesWithSubstring("load"));
199
200 // Show what happens when changing alignment to 2**29.
201 const uint64_t Align29[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700202 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800203 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator,
204 };
John Porto8eefffa2015-06-11 15:14:37 -0700205 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800206 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800207 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700208 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800209 EXPECT_EQ(" %v0 = load i32* %p0, align 536870912;\n"
210 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
211 DumpMunger.getLinesWithSubstring("load"));
212
213 // Show what happens when changing alignment to 2**30.
214 const uint64_t Align30[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700215 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800216 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator,
217 };
John Porto8eefffa2015-06-11 15:14:37 -0700218 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800219 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800220 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700221 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800222 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n"
223 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
224 DumpMunger.getLinesWithSubstring("load"));
225}
226
227// Test how we recognize alignments in load float instructions.
228TEST(IceParseInstsTests, LoadFloatAlignment) {
229 const uint64_t BitcodeRecords[] = {
230 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
231 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator,
232 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator,
233 3, naclbitc::TYPE_CODE_FLOAT, Terminator,
234 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator,
235 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, Terminator,
236 0, naclbitc::BLK_CODE_EXIT, Terminator,
237 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator,
238 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
239 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
240 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator,
241 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator,
242 0, naclbitc::BLK_CODE_EXIT, Terminator,
243 0, naclbitc::BLK_CODE_EXIT, Terminator};
244
245 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_LOAD
246
247 // Show text when alignment is 1.
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700248 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
249 EXPECT_TRUE(DumpMunger.runTest());
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800250 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load float* "
251 "%p0, align 1;\n",
252 DumpMunger.getLinesWithSubstring("58:4"));
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700253 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
254 EXPECT_TRUE(Munger.runTest());
Karl Schimpfaf238b22015-01-20 12:19:15 -0800255
256 // Show what happens when changing alignment to 0.
257 const uint64_t Align0[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700258 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800259 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator,
260 };
John Porto8eefffa2015-06-11 15:14:37 -0700261 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800262 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800263 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700264 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800265 EXPECT_EQ(
266 " %v0 = load float* %p0, align 0;\n"
Jim Stichnothdd842db2015-01-27 12:53:53 -0800267 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
268 DumpMunger.getLinesWithSubstring("load"));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800269
270 // Show what happens when changing alignment to 4.
271 const uint64_t Align4[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700272 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800273 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator,
274 };
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700275 EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
276 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800277 EXPECT_EQ(" %v0 = load float* %p0, align 4;\n",
278 DumpMunger.getLinesWithSubstring("load"));
279
280 const uint64_t Align29[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700281 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800282 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator,
283 };
John Porto8eefffa2015-06-11 15:14:37 -0700284 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800285 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800286 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700287 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800288 EXPECT_EQ(
289 " %v0 = load float* %p0, align 536870912;\n"
Jim Stichnothdd842db2015-01-27 12:53:53 -0800290 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
291 DumpMunger.getLinesWithSubstring("load"));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800292
293 // Show what happens when changing alignment to 2**30.
294 const uint64_t Align30[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700295 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800296 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator,
297 };
John Porto8eefffa2015-06-11 15:14:37 -0700298 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800299 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800300 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700301 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800302 EXPECT_EQ(
303 " %v0 = load float* %p0, align 0;\n"
Jim Stichnothdd842db2015-01-27 12:53:53 -0800304 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
305 DumpMunger.getLinesWithSubstring("load"));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800306}
307
308// Test how we recognize alignments in store instructions.
309TEST(NaClParseInstsTests, StoreAlignment) {
310 const uint64_t BitcodeRecords[] = {
311 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
312 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator,
313 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator,
314 3, naclbitc::TYPE_CODE_FLOAT, Terminator,
315 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator,
316 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, 0, Terminator,
317 0, naclbitc::BLK_CODE_EXIT, Terminator,
318 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator,
319 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
320 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
321 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(0), Terminator,
322 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator,
323 0, naclbitc::BLK_CODE_EXIT, Terminator,
324 0, naclbitc::BLK_CODE_EXIT, Terminator};
325
326 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_STORE
327
328 // Show text when alignment is 1.
329 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords),
330 Terminator);
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800331 EXPECT_TRUE(DumpMunger.runTest("Good Store Alignment 1"));
332 EXPECT_EQ(" 62:4| 3: <24, 2, 1, 1> | store float %p1, "
333 "float* %p0, \n",
334 DumpMunger.getLinesWithSubstring("62:4"));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800335 IceTest::SubzeroBitcodeMunger Munger(
336 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator);
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700337 EXPECT_TRUE(Munger.runTest());
Karl Schimpfaf238b22015-01-20 12:19:15 -0800338
339 // Show what happens when changing alignment to 0.
340 const uint64_t Align0[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700341 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800342 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignZero(), Terminator,
343 };
John Porto8eefffa2015-06-11 15:14:37 -0700344 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800345 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800346 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700347 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800348 EXPECT_EQ(
349 " store float %p1, float* %p0, align 0;\n"
350 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
351 DumpMunger.getLinesWithSubstring("store"));
352
353 // Show what happens when changing alignment to 4.
354 const uint64_t Align4[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700355 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800356 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(2), Terminator,
357 };
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700358 EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
359 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800360
361 // Show what happens when changing alignment to 8.
362 const uint64_t Align8[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700363 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800364 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(3), Terminator,
365 };
John Porto8eefffa2015-06-11 15:14:37 -0700366 EXPECT_FALSE(Munger.runTest(ARRAY(Align8), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800367 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800368 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700369 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align8)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800370 EXPECT_EQ(
371 " store float %p1, float* %p0, align 8;\n"
372 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
373 DumpMunger.getLinesWithSubstring("store"));
374
375 // Show what happens when changing alignment to 2**29.
376 const uint64_t Align29[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700377 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800378 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(29), Terminator,
379 };
John Porto8eefffa2015-06-11 15:14:37 -0700380 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800381 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800382 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700383 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800384 EXPECT_EQ(
385 " store float %p1, float* %p0, align 536870912;\n"
386 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
387 DumpMunger.getLinesWithSubstring("store"));
388
389 const uint64_t Align30[] = {
Karl Schimpf0e7e4122015-04-30 15:32:04 -0700390 ReplaceIndex, NaClMungedBitcode::Replace,
Karl Schimpfaf238b22015-01-20 12:19:15 -0800391 // Note: alignment stored as 0 or log2(Alignment)+1.
392 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(30), Terminator,
393 };
John Porto8eefffa2015-06-11 15:14:37 -0700394 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
Karl Schimpf22ed4eb2015-03-04 12:17:20 -0800395 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n",
Karl Schimpfaf238b22015-01-20 12:19:15 -0800396 Munger.getTestResults());
Karl Schimpfcbb1d3d2015-06-08 09:25:15 -0700397 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
Karl Schimpfaf238b22015-01-20 12:19:15 -0800398 EXPECT_EQ(
399 " store float %p1, float* %p0, align 0;\n"
400 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
401 DumpMunger.getLinesWithSubstring("store"));
402}
403
Karl Schimpf2e7daef2015-01-09 13:04:13 -0800404} // end of anonymous namespace