OLD | NEW |
1 //===- unittest/IceParseInstsTest.cpp - test instruction errors -----------===// | 1 //===- unittest/IceParseInstsTest.cpp - test instruction errors -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "llvm/ADT/STLExtras.h" | 10 #include "llvm/ADT/STLExtras.h" |
11 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | 11 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
12 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" | 12 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
13 | 13 |
14 #include "BitcodeMunge.h" | 14 #include "BitcodeMunge.h" |
15 | 15 |
16 #include "gtest/gtest.h" | 16 #include "gtest/gtest.h" |
17 | 17 |
18 using namespace llvm; | 18 using namespace llvm; |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 static const uint64_t Terminator = 0x5768798008978675LL; | 22 static const uint64_t Terminator = 0x5768798008978675LL; |
23 | 23 |
| 24 // Note: alignment stored as 0 or log2(Alignment)+1. |
| 25 uint64_t getEncAlignPower(unsigned Power) { |
| 26 return Power + 1; |
| 27 } |
| 28 uint64_t getEncAlignZero() { return 0; } |
| 29 |
24 /// Test how we report a call arg that refers to nonexistent call argument | 30 /// Test how we report a call arg that refers to nonexistent call argument |
25 TEST(IceParseInstsTest, NonexistentCallArg) { | 31 TEST(IceParseInstsTest, NonexistentCallArg) { |
26 const uint64_t BitcodeRecords[] = { | 32 const uint64_t BitcodeRecords[] = { |
27 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, | 33 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
28 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, | 34 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
29 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, | 35 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
30 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, | 36 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
31 3, naclbitc::TYPE_CODE_VOID, Terminator, | 37 3, naclbitc::TYPE_CODE_VOID, Terminator, |
32 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator, | 38 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator, |
33 0, naclbitc::BLK_CODE_EXIT, Terminator, | 39 0, naclbitc::BLK_CODE_EXIT, Terminator, |
34 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 1, 0, Terminator, | 40 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 1, 0, Terminator, |
35 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, | 41 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
36 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, | 42 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
37 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, | 43 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
38 // Note: 100 is a bad value index in next line. | 44 // Note: 100 is a bad value index in next line. |
39 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator, | 45 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator, |
40 3, naclbitc::FUNC_CODE_INST_RET, Terminator, | 46 3, naclbitc::FUNC_CODE_INST_RET, Terminator, |
41 0, naclbitc::BLK_CODE_EXIT, Terminator, | 47 0, naclbitc::BLK_CODE_EXIT, Terminator, |
42 0, naclbitc::BLK_CODE_EXIT, Terminator | 48 0, naclbitc::BLK_CODE_EXIT, Terminator |
43 }; | 49 }; |
44 | 50 |
45 | |
46 // Show bitcode objdump for BitcodeRecords. | 51 // Show bitcode objdump for BitcodeRecords. |
47 NaClObjDumpMunger DumpMunger(BitcodeRecords, | 52 NaClObjDumpMunger DumpMunger(BitcodeRecords, |
48 array_lengthof(BitcodeRecords), Terminator); | 53 array_lengthof(BitcodeRecords), Terminator); |
49 EXPECT_FALSE(DumpMunger.runTestForAssembly("Nonexistent call arg")); | 54 EXPECT_FALSE(DumpMunger.runTestForAssembly("Nonexistent call arg")); |
50 EXPECT_EQ( | 55 EXPECT_EQ( |
51 "module { // BlockID = 8\n" | 56 "module { // BlockID = 8\n" |
52 " types { // BlockID = 17\n" | 57 " types { // BlockID = 17\n" |
53 " count 3;\n" | 58 " count 3;\n" |
54 " @t0 = i32;\n" | 59 " @t0 = i32;\n" |
55 " @t1 = void;\n" | 60 " @t1 = void;\n" |
(...skipping 13 matching lines...) Expand all Loading... |
69 | 74 |
70 // Show that we get appropriate error when parsing in Subzero. | 75 // Show that we get appropriate error when parsing in Subzero. |
71 IceTest::SubzeroBitcodeMunger Munger( | 76 IceTest::SubzeroBitcodeMunger Munger( |
72 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); | 77 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
73 EXPECT_FALSE(Munger.runTest("Nonexistent call arg")); | 78 EXPECT_FALSE(Munger.runTest("Nonexistent call arg")); |
74 EXPECT_EQ( | 79 EXPECT_EQ( |
75 "Error: (66:4) Invalid function record: <34 0 4 2 100>\n", | 80 "Error: (66:4) Invalid function record: <34 0 4 2 100>\n", |
76 Munger.getTestResults()); | 81 Munger.getTestResults()); |
77 } | 82 } |
78 | 83 |
| 84 /// Test how we recognize alignments in alloca instructions. |
| 85 TEST(IceParseInstsTests, AllocaAlignment) { |
| 86 const uint64_t BitcodeRecords[] = { |
| 87 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 88 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 89 3, naclbitc::TYPE_CODE_NUMENTRY, 4, Terminator, |
| 90 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 91 3, naclbitc::TYPE_CODE_VOID, Terminator, |
| 92 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, Terminator, |
| 93 3, naclbitc::TYPE_CODE_INTEGER, 8, Terminator, |
| 94 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 95 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 96 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 97 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 98 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(0), Terminator, |
| 99 3, naclbitc::FUNC_CODE_INST_RET, Terminator, |
| 100 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 101 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| 102 |
| 103 const uint64_t ReplaceIndex = 11; // index for FUNC_CODE_INST_ALLOCA |
| 104 |
| 105 // Show text when alignment is 1. |
| 106 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| 107 Terminator); |
| 108 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good alloca alignment 1")); |
| 109 EXPECT_EQ("module { // BlockID = 8\n" |
| 110 " types { // BlockID = 17\n" |
| 111 " count 4;\n" |
| 112 " @t0 = i32;\n" |
| 113 " @t1 = void;\n" |
| 114 " @t2 = void (i32);\n" |
| 115 " @t3 = i8;\n" |
| 116 " }\n" |
| 117 " define external void @f0(i32);\n" |
| 118 " function void @f0(i32 %p0) { // BlockID = 12\n" |
| 119 " blocks 1;\n" |
| 120 " %b0:\n" |
| 121 " %v0 = alloca i8, i32 %p0, align 1;\n" |
| 122 " ret void;\n" |
| 123 " }\n" |
| 124 "}\n", |
| 125 DumpMunger.getTestResults()); |
| 126 |
| 127 // Show that we can handle alignment of 1. |
| 128 IceTest::SubzeroBitcodeMunger Munger( |
| 129 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| 130 EXPECT_TRUE(Munger.runTest("Good alloca alignment 1")); |
| 131 |
| 132 // Show what happens when changing alignment to 0. |
| 133 const uint64_t Align0[] = { |
| 134 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 135 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignZero(), Terminator, |
| 136 }; |
| 137 EXPECT_TRUE(Munger.runTest("Good alloca alignment 0", Align0, |
| 138 array_lengthof(Align0))); |
| 139 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good alloca alignment 0", Align0, |
| 140 array_lengthof(Align0))); |
| 141 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", |
| 142 DumpMunger.getLinesWithSubstring("alloca")); |
| 143 |
| 144 // Show what happens when changing alignment to 2**30. |
| 145 const uint64_t Align30[] = { |
| 146 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 147 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(30), Terminator, |
| 148 }; |
| 149 EXPECT_FALSE(Munger.runTest("Bad alloca alignment 30", Align30, |
| 150 array_lengthof(Align30))); |
| 151 EXPECT_EQ("Error: (62:4) Invalid function record: <19 1 31>\n", |
| 152 Munger.getTestResults()); |
| 153 |
| 154 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad alloca alignment 30", Align30, |
| 155 array_lengthof(Align30))); |
| 156 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", |
| 157 DumpMunger.getLinesWithSubstring("alloca")); |
| 158 EXPECT_EQ( |
| 159 "Error(62:4): Alignment can't be greater than 2**29. Found: 2**30\n", |
| 160 DumpMunger.getLinesWithSubstring("Error")); |
| 161 |
| 162 // Show what happens when changing alignment to 2**29. |
| 163 const uint64_t Align29[] = { |
| 164 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 165 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(29), Terminator, |
| 166 }; |
| 167 EXPECT_TRUE(Munger.runTest("Good alloca alignment 29", Align29, |
| 168 array_lengthof(Align29))); |
| 169 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good alloca alignment 29", Align29, |
| 170 array_lengthof(Align29))); |
| 171 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 536870912;\n", |
| 172 DumpMunger.getLinesWithSubstring("alloca")); |
| 173 } |
| 174 |
| 175 // Test how we recognize alignments in load i32 instructions. |
| 176 TEST(IceParseInstsTests, LoadI32Alignment) { |
| 177 const uint64_t BitcodeRecords[] = { |
| 178 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 179 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 180 3, naclbitc::TYPE_CODE_NUMENTRY, 2, Terminator, |
| 181 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 182 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 0, Terminator, |
| 183 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 184 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator, |
| 185 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 186 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 187 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, |
| 188 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 189 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 190 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| 191 |
| 192 const uint64_t ReplaceIndex = 9; // index for FUNC_CODE_INST_LOAD |
| 193 |
| 194 // Show text when alignment is 1. |
| 195 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| 196 Terminator); |
| 197 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good load i32 alignment 1")); |
| 198 EXPECT_EQ("module { // BlockID = 8\n" |
| 199 " types { // BlockID = 17\n" |
| 200 " count 2;\n" |
| 201 " @t0 = i32;\n" |
| 202 " @t1 = i32 (i32);\n" |
| 203 " }\n" |
| 204 " define external i32 @f0(i32);\n" |
| 205 " function i32 @f0(i32 %p0) { // BlockID = 12\n" |
| 206 " blocks 1;\n" |
| 207 " %b0:\n" |
| 208 " %v0 = load i32* %p0, align 1;\n" |
| 209 " ret i32 %v0;\n" |
| 210 " }\n" |
| 211 "}\n", |
| 212 DumpMunger.getTestResults()); |
| 213 IceTest::SubzeroBitcodeMunger Munger( |
| 214 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| 215 EXPECT_TRUE(Munger.runTest("Good load i32 alignment 1")); |
| 216 |
| 217 // Show what happens when changing alignment to 0. |
| 218 const uint64_t Align0[] = { |
| 219 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 220 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, |
| 221 }; |
| 222 EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 0", Align0, |
| 223 array_lengthof(Align0))); |
| 224 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 0 0>\n", |
| 225 Munger.getTestResults()); |
| 226 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 0", Align0, |
| 227 array_lengthof(Align0))); |
| 228 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" |
| 229 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| 230 DumpMunger.getLinesWithSubstring("load")); |
| 231 |
| 232 // Show what happens when changing alignment to 4. |
| 233 const uint64_t Align4[] = { |
| 234 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 235 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, |
| 236 }; |
| 237 EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 4", Align4, |
| 238 array_lengthof(Align4))); |
| 239 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 3 0>\n", |
| 240 Munger.getTestResults()); |
| 241 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 4", Align4, |
| 242 array_lengthof(Align4))); |
| 243 EXPECT_EQ(" %v0 = load i32* %p0, align 4;\n" |
| 244 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| 245 DumpMunger.getLinesWithSubstring("load")); |
| 246 |
| 247 // Show what happens when changing alignment to 2**29. |
| 248 const uint64_t Align29[] = { |
| 249 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 250 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, |
| 251 }; |
| 252 EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 29", Align29, |
| 253 array_lengthof(Align29))); |
| 254 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 30 0>\n", |
| 255 Munger.getTestResults()); |
| 256 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 29", |
| 257 Align29, array_lengthof(Align29))); |
| 258 EXPECT_EQ(" %v0 = load i32* %p0, align 536870912;\n" |
| 259 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| 260 DumpMunger.getLinesWithSubstring("load")); |
| 261 |
| 262 // Show what happens when changing alignment to 2**30. |
| 263 const uint64_t Align30[] = { |
| 264 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 265 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, |
| 266 }; |
| 267 EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 30", Align30, |
| 268 array_lengthof(Align30))); |
| 269 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 31 0>\n", |
| 270 Munger.getTestResults()); |
| 271 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 30", |
| 272 Align30, array_lengthof(Align30))); |
| 273 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" |
| 274 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| 275 DumpMunger.getLinesWithSubstring("load")); |
| 276 } |
| 277 |
| 278 // Test how we recognize alignments in load float instructions. |
| 279 TEST(IceParseInstsTests, LoadFloatAlignment) { |
| 280 const uint64_t BitcodeRecords[] = { |
| 281 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 282 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 283 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
| 284 3, naclbitc::TYPE_CODE_FLOAT, Terminator, |
| 285 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 286 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, Terminator, |
| 287 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 288 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 289 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 290 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 291 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, |
| 292 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 293 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 294 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| 295 |
| 296 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_LOAD |
| 297 |
| 298 // Show text when alignment is 1. |
| 299 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| 300 Terminator); |
| 301 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good load float alignment 1")); |
| 302 EXPECT_EQ("module { // BlockID = 8\n" |
| 303 " types { // BlockID = 17\n" |
| 304 " count 3;\n" |
| 305 " @t0 = float;\n" |
| 306 " @t1 = i32;\n" |
| 307 " @t2 = float (i32);\n" |
| 308 " }\n" |
| 309 " define external float @f0(i32);\n" |
| 310 " function float @f0(i32 %p0) { // BlockID = 12\n" |
| 311 " blocks 1;\n" |
| 312 " %b0:\n" |
| 313 " %v0 = load float* %p0, align 1;\n" |
| 314 " ret float %v0;\n" |
| 315 " }\n" |
| 316 "}\n", |
| 317 DumpMunger.getTestResults()); |
| 318 IceTest::SubzeroBitcodeMunger Munger( |
| 319 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| 320 EXPECT_TRUE(Munger.runTest("Good load float alignment 1")); |
| 321 |
| 322 // Show what happens when changing alignment to 0. |
| 323 const uint64_t Align0[] = { |
| 324 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 325 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, |
| 326 }; |
| 327 EXPECT_FALSE(Munger.runTest("Bad load float alignment 0", Align0, |
| 328 array_lengthof(Align0))); |
| 329 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 0 0>\n", |
| 330 Munger.getTestResults()); |
| 331 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 0", |
| 332 Align0, array_lengthof(Align0))); |
| 333 EXPECT_EQ( |
| 334 " %v0 = load float* %p0, align 0;\n" |
| 335 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| 336 DumpMunger.getLinesWithSubstring("load")); |
| 337 |
| 338 // Show what happens when changing alignment to 4. |
| 339 const uint64_t Align4[] = { |
| 340 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 341 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, |
| 342 }; |
| 343 EXPECT_TRUE(Munger.runTest("Good load float alignment 4", Align4, |
| 344 array_lengthof(Align4))); |
| 345 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good load float alignment 4", |
| 346 Align4, array_lengthof(Align4))); |
| 347 EXPECT_EQ(" %v0 = load float* %p0, align 4;\n", |
| 348 DumpMunger.getLinesWithSubstring("load")); |
| 349 |
| 350 const uint64_t Align29[] = { |
| 351 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 352 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, |
| 353 }; |
| 354 EXPECT_FALSE(Munger.runTest("Bad load float alignment 29", Align29, |
| 355 array_lengthof(Align29))); |
| 356 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 30 0>\n", |
| 357 Munger.getTestResults()); |
| 358 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 29", |
| 359 Align29, array_lengthof(Align29))); |
| 360 EXPECT_EQ( |
| 361 " %v0 = load float* %p0, align 536870912;\n" |
| 362 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| 363 DumpMunger.getLinesWithSubstring("load")); |
| 364 |
| 365 // Show what happens when changing alignment to 2**30. |
| 366 const uint64_t Align30[] = { |
| 367 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 368 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, |
| 369 }; |
| 370 EXPECT_FALSE(Munger.runTest("Bad load float alignment 30", Align30, |
| 371 array_lengthof(Align30))); |
| 372 EXPECT_EQ("Error: (58:4) Invalid function record: <20 1 31 0>\n", |
| 373 Munger.getTestResults()); |
| 374 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 30", |
| 375 Align30, array_lengthof(Align30))); |
| 376 EXPECT_EQ( |
| 377 " %v0 = load float* %p0, align 0;\n" |
| 378 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| 379 DumpMunger.getLinesWithSubstring("load")); |
| 380 } |
| 381 |
| 382 // Test how we recognize alignments in store instructions. |
| 383 TEST(NaClParseInstsTests, StoreAlignment) { |
| 384 const uint64_t BitcodeRecords[] = { |
| 385 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 386 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 387 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
| 388 3, naclbitc::TYPE_CODE_FLOAT, Terminator, |
| 389 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 390 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, 0, Terminator, |
| 391 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 392 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 393 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 394 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 395 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(0), Terminator, |
| 396 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 397 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 398 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| 399 |
| 400 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_STORE |
| 401 |
| 402 // Show text when alignment is 1. |
| 403 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| 404 Terminator); |
| 405 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good Store Alignment 1")); |
| 406 EXPECT_EQ("module { // BlockID = 8\n" |
| 407 " types { // BlockID = 17\n" |
| 408 " count 3;\n" |
| 409 " @t0 = float;\n" |
| 410 " @t1 = i32;\n" |
| 411 " @t2 = float (i32, float);\n" |
| 412 " }\n" |
| 413 " define external float @f0(i32, float);\n" |
| 414 " function float @f0(i32 %p0, float %p1) { // BlockID = 12\n" |
| 415 " blocks 1;\n" |
| 416 " %b0:\n" |
| 417 " store float %p1, float* %p0, align 1;\n" |
| 418 " ret float %p1;\n" |
| 419 " }\n" |
| 420 "}\n", |
| 421 DumpMunger.getTestResults()); |
| 422 IceTest::SubzeroBitcodeMunger Munger( |
| 423 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| 424 EXPECT_TRUE(Munger.runTest("Good store alignment")); |
| 425 |
| 426 // Show what happens when changing alignment to 0. |
| 427 const uint64_t Align0[] = { |
| 428 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 429 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignZero(), Terminator, |
| 430 }; |
| 431 EXPECT_FALSE( |
| 432 Munger.runTest("Bad store alignment 0", Align0, array_lengthof(Align0))); |
| 433 EXPECT_EQ("Error: (62:4) Invalid function record: <24 2 1 0>\n", |
| 434 Munger.getTestResults()); |
| 435 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 0", Align0, |
| 436 array_lengthof(Align0))); |
| 437 EXPECT_EQ( |
| 438 " store float %p1, float* %p0, align 0;\n" |
| 439 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| 440 DumpMunger.getLinesWithSubstring("store")); |
| 441 |
| 442 // Show what happens when changing alignment to 4. |
| 443 const uint64_t Align4[] = { |
| 444 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 445 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(2), Terminator, |
| 446 }; |
| 447 EXPECT_TRUE( |
| 448 Munger.runTest("Bad store alignment 4", Align4, array_lengthof(Align4))); |
| 449 EXPECT_TRUE(DumpMunger.runTestForAssembly("Good store alignment 4", Align4, |
| 450 array_lengthof(Align4))); |
| 451 |
| 452 // Show what happens when changing alignment to 8. |
| 453 const uint64_t Align8[] = { |
| 454 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 455 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(3), Terminator, |
| 456 }; |
| 457 EXPECT_FALSE( |
| 458 Munger.runTest("Bad store alignment 8", Align8, array_lengthof(Align8))); |
| 459 EXPECT_EQ("Error: (62:4) Invalid function record: <24 2 1 4>\n", |
| 460 Munger.getTestResults()); |
| 461 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 8", Align8, |
| 462 array_lengthof(Align8))); |
| 463 EXPECT_EQ( |
| 464 " store float %p1, float* %p0, align 8;\n" |
| 465 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| 466 DumpMunger.getLinesWithSubstring("store")); |
| 467 |
| 468 // Show what happens when changing alignment to 2**29. |
| 469 const uint64_t Align29[] = { |
| 470 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 471 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(29), Terminator, |
| 472 }; |
| 473 EXPECT_FALSE(Munger.runTest("Bad store alignment 29", Align29, |
| 474 array_lengthof(Align29))); |
| 475 EXPECT_EQ("Error: (62:4) Invalid function record: <24 2 1 30>\n", |
| 476 Munger.getTestResults()); |
| 477 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 29", Align29, |
| 478 array_lengthof(Align29))); |
| 479 EXPECT_EQ( |
| 480 " store float %p1, float* %p0, align 536870912;\n" |
| 481 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| 482 DumpMunger.getLinesWithSubstring("store")); |
| 483 |
| 484 const uint64_t Align30[] = { |
| 485 ReplaceIndex, NaClBitcodeMunger::Replace, |
| 486 // Note: alignment stored as 0 or log2(Alignment)+1. |
| 487 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(30), Terminator, |
| 488 }; |
| 489 EXPECT_FALSE(Munger.runTest("Bad store alignment 30", Align30, |
| 490 array_lengthof(Align30))); |
| 491 EXPECT_EQ("Error: (62:4) Invalid function record: <24 2 1 31>\n", |
| 492 Munger.getTestResults()); |
| 493 EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad Store alignment 30", Align30, |
| 494 array_lengthof(Align30))); |
| 495 EXPECT_EQ( |
| 496 " store float %p1, float* %p0, align 0;\n" |
| 497 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| 498 DumpMunger.getLinesWithSubstring("store")); |
| 499 } |
| 500 |
79 } // end of anonymous namespace | 501 } // end of anonymous namespace |
OLD | NEW |