1 //===- 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
10 #include <string>
11
12 #pragma clang diagnostic push
13 #pragma clang diagnostic ignored "-Wunused-parameter"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
16 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
17 #pragma clang diagnostic pop
18
19 #include "BitcodeMunge.h"
20 #include "unittests/Bitcode/NaClMungeTest.h"
21
22 using namespace llvm;
23 using namespace naclmungetest;
24
25 namespace {
26
27 // The ParseError constant is passed to the BitcodeMunger to prevent translation
28 // when we expect a Parse error.
29 constexpr bool ParseError = true;
30
31 // Note: alignment stored as 0 or log2(Alignment)+1.
getEncAlignPower(unsigned Power)32 uint64_t getEncAlignPower(unsigned Power) { return Power + 1; }
getEncAlignZero()33 uint64_t getEncAlignZero() { return 0; }
34
35 /// Test how we report a call arg that refers to nonexistent call argument
TEST(IceParseInstsTest,NonexistentCallArg)36 TEST(IceParseInstsTest, NonexistentCallArg) {
37 const uint64_t BitcodeRecords[] = {
38 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 1,
39 naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 3,
40 naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, 3,
41 naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 3, naclbitc::TYPE_CODE_VOID,
42 Terminator, 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator, 0,
43 naclbitc::BLK_CODE_EXIT, Terminator, 3, naclbitc::MODULE_CODE_FUNCTION, 2,
44 0, 1, 3, Terminator, 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3,
45 Terminator, 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2,
46 Terminator, 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
47 // Note: 100 is a bad value index in next line.
48 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator, 3,
49 naclbitc::FUNC_CODE_INST_RET, Terminator, 0, naclbitc::BLK_CODE_EXIT,
50 Terminator, 0, naclbitc::BLK_CODE_EXIT, Terminator};
51
52 // Show bitcode objdump for BitcodeRecords.
53 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
54 EXPECT_FALSE(DumpMunger.runTest());
55 EXPECT_EQ(" 66:4| 3: <34, 0, 4, 2, 100> | call void @f0(i32 "
56 "%p0, i32 @f0);\n"
57 "Error(66:4): Invalid relative value id: 100 (Must be <= 4)\n",
58 DumpMunger.getLinesWithSubstring("66:4"));
59
60 // Show that we get appropriate error when parsing in Subzero.
61 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
62 EXPECT_FALSE(Munger.runTest(ParseError));
63 EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n",
64 Munger.getTestResults());
65
66 // Show that we generate a fatal error when not allowing error recovery.
67 Ice::ClFlags::Flags.setAllowErrorRecovery(false);
68 EXPECT_DEATH(Munger.runTest(ParseError), ".*ERROR: Unable to continue.*");
69 }
70
71 /// Test how we recognize alignments in alloca instructions.
TEST(IceParseInstsTests,AllocaAlignment)72 TEST(IceParseInstsTests, AllocaAlignment) {
73 const uint64_t BitcodeRecords[] = {1,
74 naclbitc::BLK_CODE_ENTER,
75 naclbitc::MODULE_BLOCK_ID,
76 2,
77 Terminator,
78 1,
79 naclbitc::BLK_CODE_ENTER,
80 naclbitc::TYPE_BLOCK_ID_NEW,
81 2,
82 Terminator,
83 3,
84 naclbitc::TYPE_CODE_NUMENTRY,
85 4,
86 Terminator,
87 3,
88 naclbitc::TYPE_CODE_INTEGER,
89 32,
90 Terminator,
91 3,
92 naclbitc::TYPE_CODE_VOID,
93 Terminator,
94 3,
95 naclbitc::TYPE_CODE_FUNCTION,
96 0,
97 1,
98 0,
99 Terminator,
100 3,
101 naclbitc::TYPE_CODE_INTEGER,
102 8,
103 Terminator,
104 0,
105 naclbitc::BLK_CODE_EXIT,
106 Terminator,
107 3,
108 naclbitc::MODULE_CODE_FUNCTION,
109 2,
110 0,
111 0,
112 3,
113 Terminator,
114 1,
115 naclbitc::BLK_CODE_ENTER,
116 naclbitc::FUNCTION_BLOCK_ID,
117 2,
118 Terminator,
119 3,
120 naclbitc::FUNC_CODE_DECLAREBLOCKS,
121 1,
122 Terminator,
123 3,
124 naclbitc::FUNC_CODE_INST_ALLOCA,
125 1,
126 getEncAlignPower(0),
127 Terminator,
128 3,
129 naclbitc::FUNC_CODE_INST_RET,
130 Terminator,
131 0,
132 naclbitc::BLK_CODE_EXIT,
133 Terminator,
134 0,
135 naclbitc::BLK_CODE_EXIT,
136 Terminator};
137
138 const uint64_t ReplaceIndex = 11; // index for FUNC_CODE_INST_ALLOCA
139
140 // Show text when alignment is 1.
141 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
142 EXPECT_TRUE(DumpMunger.runTest());
143 EXPECT_EQ(" 62:4| 3: <19, 1, 1> | %v0 = alloca i8, i32 "
144 "%p0, align 1;\n",
145 DumpMunger.getLinesWithSubstring("62:4"));
146
147 // Show that we can handle alignment of 1.
148 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
149 EXPECT_TRUE(Munger.runTest());
150
151 // Show what happens when changing alignment to 0.
152 const uint64_t Align0[] = {
153 ReplaceIndex,
154 NaClMungedBitcode::Replace,
155 3,
156 naclbitc::FUNC_CODE_INST_ALLOCA,
157 1,
158 getEncAlignZero(),
159 Terminator,
160 };
161 EXPECT_TRUE(Munger.runTest(ARRAY(Align0)));
162 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
163 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n",
164 DumpMunger.getLinesWithSubstring("alloca"));
165
166 // Show what happens when changing alignment to 2**30.
167 const uint64_t Align30[] = {
168 ReplaceIndex,
169 NaClMungedBitcode::Replace,
170 3,
171 naclbitc::FUNC_CODE_INST_ALLOCA,
172 1,
173 getEncAlignPower(30),
174 Terminator,
175 };
176 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
177 EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n",
178 Munger.getTestResults());
179
180 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
181 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n",
182 DumpMunger.getLinesWithSubstring("alloca"));
183 EXPECT_EQ(
184 "Error(62:4): Alignment can't be greater than 2**29. Found: 2**30\n",
185 DumpMunger.getLinesWithSubstring("Error"));
186
187 // Show what happens when changing alignment to 2**29.
188 const uint64_t Align29[] = {
189 ReplaceIndex,
190 NaClMungedBitcode::Replace,
191 3,
192 naclbitc::FUNC_CODE_INST_ALLOCA,
193 1,
194 getEncAlignPower(29),
195 Terminator,
196 };
197 EXPECT_TRUE(Munger.runTest(ARRAY(Align29)));
198 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
199 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 536870912;\n",
200 DumpMunger.getLinesWithSubstring("alloca"));
201 }
202
203 // Test how we recognize alignments in load i32 instructions.
TEST(IceParseInstsTests,LoadI32Alignment)204 TEST(IceParseInstsTests, LoadI32Alignment) {
205 const uint64_t BitcodeRecords[] = {1,
206 naclbitc::BLK_CODE_ENTER,
207 naclbitc::MODULE_BLOCK_ID,
208 2,
209 Terminator,
210 1,
211 naclbitc::BLK_CODE_ENTER,
212 naclbitc::TYPE_BLOCK_ID_NEW,
213 2,
214 Terminator,
215 3,
216 naclbitc::TYPE_CODE_NUMENTRY,
217 2,
218 Terminator,
219 3,
220 naclbitc::TYPE_CODE_INTEGER,
221 32,
222 Terminator,
223 3,
224 naclbitc::TYPE_CODE_FUNCTION,
225 0,
226 0,
227 0,
228 Terminator,
229 0,
230 naclbitc::BLK_CODE_EXIT,
231 Terminator,
232 3,
233 naclbitc::MODULE_CODE_FUNCTION,
234 1,
235 0,
236 0,
237 3,
238 Terminator,
239 1,
240 naclbitc::BLK_CODE_ENTER,
241 naclbitc::FUNCTION_BLOCK_ID,
242 2,
243 Terminator,
244 3,
245 naclbitc::FUNC_CODE_DECLAREBLOCKS,
246 1,
247 Terminator,
248 3,
249 naclbitc::FUNC_CODE_INST_LOAD,
250 1,
251 getEncAlignPower(0),
252 0,
253 Terminator,
254 3,
255 naclbitc::FUNC_CODE_INST_RET,
256 1,
257 Terminator,
258 0,
259 naclbitc::BLK_CODE_EXIT,
260 Terminator,
261 0,
262 naclbitc::BLK_CODE_EXIT,
263 Terminator};
264
265 const uint64_t ReplaceIndex = 9; // index for FUNC_CODE_INST_LOAD
266
267 // Show text when alignment is 1.
268 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
269 EXPECT_TRUE(DumpMunger.runTest());
270 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load i32* %p0, "
271 "align 1;\n",
272 DumpMunger.getLinesWithSubstring("58:4"));
273 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
274 EXPECT_TRUE(Munger.runTest());
275
276 // Show what happens when changing alignment to 0.
277 const uint64_t Align0[] = {
278 ReplaceIndex,
279 NaClMungedBitcode::Replace,
280 3,
281 naclbitc::FUNC_CODE_INST_LOAD,
282 1,
283 getEncAlignZero(),
284 0,
285 Terminator,
286 };
287 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
288 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
289 Munger.getTestResults());
290 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
291 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n"
292 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
293 DumpMunger.getLinesWithSubstring("load"));
294
295 // Show what happens when changing alignment to 4.
296 const uint64_t Align4[] = {
297 ReplaceIndex,
298 NaClMungedBitcode::Replace,
299 3,
300 naclbitc::FUNC_CODE_INST_LOAD,
301 1,
302 getEncAlignPower(2),
303 0,
304 Terminator,
305 };
306 EXPECT_FALSE(Munger.runTest(ARRAY(Align4), ParseError));
307 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n",
308 Munger.getTestResults());
309 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
310 EXPECT_EQ(" %v0 = load i32* %p0, align 4;\n"
311 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
312 DumpMunger.getLinesWithSubstring("load"));
313
314 // Show what happens when changing alignment to 2**29.
315 const uint64_t Align29[] = {
316 ReplaceIndex,
317 NaClMungedBitcode::Replace,
318 3,
319 naclbitc::FUNC_CODE_INST_LOAD,
320 1,
321 getEncAlignPower(29),
322 0,
323 Terminator,
324 };
325 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
326 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
327 Munger.getTestResults());
328 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
329 EXPECT_EQ(" %v0 = load i32* %p0, align 536870912;\n"
330 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
331 DumpMunger.getLinesWithSubstring("load"));
332
333 // Show what happens when changing alignment to 2**30.
334 const uint64_t Align30[] = {
335 ReplaceIndex,
336 NaClMungedBitcode::Replace,
337 3,
338 naclbitc::FUNC_CODE_INST_LOAD,
339 1,
340 getEncAlignPower(30),
341 0,
342 Terminator,
343 };
344 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
345 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
346 Munger.getTestResults());
347 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
348 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n"
349 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n",
350 DumpMunger.getLinesWithSubstring("load"));
351 }
352
353 // Test how we recognize alignments in load float instructions.
TEST(IceParseInstsTests,LoadFloatAlignment)354 TEST(IceParseInstsTests, LoadFloatAlignment) {
355 const uint64_t BitcodeRecords[] = {1,
356 naclbitc::BLK_CODE_ENTER,
357 naclbitc::MODULE_BLOCK_ID,
358 2,
359 Terminator,
360 1,
361 naclbitc::BLK_CODE_ENTER,
362 naclbitc::TYPE_BLOCK_ID_NEW,
363 2,
364 Terminator,
365 3,
366 naclbitc::TYPE_CODE_NUMENTRY,
367 3,
368 Terminator,
369 3,
370 naclbitc::TYPE_CODE_FLOAT,
371 Terminator,
372 3,
373 naclbitc::TYPE_CODE_INTEGER,
374 32,
375 Terminator,
376 3,
377 naclbitc::TYPE_CODE_FUNCTION,
378 0,
379 0,
380 1,
381 Terminator,
382 0,
383 naclbitc::BLK_CODE_EXIT,
384 Terminator,
385 3,
386 naclbitc::MODULE_CODE_FUNCTION,
387 2,
388 0,
389 0,
390 3,
391 Terminator,
392 1,
393 naclbitc::BLK_CODE_ENTER,
394 naclbitc::FUNCTION_BLOCK_ID,
395 2,
396 Terminator,
397 3,
398 naclbitc::FUNC_CODE_DECLAREBLOCKS,
399 1,
400 Terminator,
401 3,
402 naclbitc::FUNC_CODE_INST_LOAD,
403 1,
404 getEncAlignPower(0),
405 0,
406 Terminator,
407 3,
408 naclbitc::FUNC_CODE_INST_RET,
409 1,
410 Terminator,
411 0,
412 naclbitc::BLK_CODE_EXIT,
413 Terminator,
414 0,
415 naclbitc::BLK_CODE_EXIT,
416 Terminator};
417
418 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_LOAD
419
420 // Show text when alignment is 1.
421 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
422 EXPECT_TRUE(DumpMunger.runTest());
423 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load float* "
424 "%p0, align 1;\n",
425 DumpMunger.getLinesWithSubstring("58:4"));
426 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
427 EXPECT_TRUE(Munger.runTest());
428
429 // Show what happens when changing alignment to 0.
430 const uint64_t Align0[] = {
431 ReplaceIndex,
432 NaClMungedBitcode::Replace,
433 3,
434 naclbitc::FUNC_CODE_INST_LOAD,
435 1,
436 getEncAlignZero(),
437 0,
438 Terminator,
439 };
440 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
441 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
442 Munger.getTestResults());
443 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
444 EXPECT_EQ(" %v0 = load float* %p0, align 0;\n"
445 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
446 DumpMunger.getLinesWithSubstring("load"));
447
448 // Show what happens when changing alignment to 4.
449 const uint64_t Align4[] = {
450 ReplaceIndex,
451 NaClMungedBitcode::Replace,
452 3,
453 naclbitc::FUNC_CODE_INST_LOAD,
454 1,
455 getEncAlignPower(2),
456 0,
457 Terminator,
458 };
459 EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
460 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
461 EXPECT_EQ(" %v0 = load float* %p0, align 4;\n",
462 DumpMunger.getLinesWithSubstring("load"));
463
464 const uint64_t Align29[] = {
465 ReplaceIndex,
466 NaClMungedBitcode::Replace,
467 3,
468 naclbitc::FUNC_CODE_INST_LOAD,
469 1,
470 getEncAlignPower(29),
471 0,
472 Terminator,
473 };
474 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
475 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
476 Munger.getTestResults());
477 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
478 EXPECT_EQ(" %v0 = load float* %p0, align 536870912;\n"
479 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
480 DumpMunger.getLinesWithSubstring("load"));
481
482 // Show what happens when changing alignment to 2**30.
483 const uint64_t Align30[] = {
484 ReplaceIndex,
485 NaClMungedBitcode::Replace,
486 3,
487 naclbitc::FUNC_CODE_INST_LOAD,
488 1,
489 getEncAlignPower(30),
490 0,
491 Terminator,
492 };
493 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
494 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
495 Munger.getTestResults());
496 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
497 EXPECT_EQ(" %v0 = load float* %p0, align 0;\n"
498 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
499 DumpMunger.getLinesWithSubstring("load"));
500 }
501
502 // Test how we recognize alignments in store instructions.
TEST(NaClParseInstsTests,StoreAlignment)503 TEST(NaClParseInstsTests, StoreAlignment) {
504 const uint64_t BitcodeRecords[] = {1,
505 naclbitc::BLK_CODE_ENTER,
506 naclbitc::MODULE_BLOCK_ID,
507 2,
508 Terminator,
509 1,
510 naclbitc::BLK_CODE_ENTER,
511 naclbitc::TYPE_BLOCK_ID_NEW,
512 2,
513 Terminator,
514 3,
515 naclbitc::TYPE_CODE_NUMENTRY,
516 3,
517 Terminator,
518 3,
519 naclbitc::TYPE_CODE_FLOAT,
520 Terminator,
521 3,
522 naclbitc::TYPE_CODE_INTEGER,
523 32,
524 Terminator,
525 3,
526 naclbitc::TYPE_CODE_FUNCTION,
527 0,
528 0,
529 1,
530 0,
531 Terminator,
532 0,
533 naclbitc::BLK_CODE_EXIT,
534 Terminator,
535 3,
536 naclbitc::MODULE_CODE_FUNCTION,
537 2,
538 0,
539 0,
540 3,
541 Terminator,
542 1,
543 naclbitc::BLK_CODE_ENTER,
544 naclbitc::FUNCTION_BLOCK_ID,
545 2,
546 Terminator,
547 3,
548 naclbitc::FUNC_CODE_DECLAREBLOCKS,
549 1,
550 Terminator,
551 3,
552 naclbitc::FUNC_CODE_INST_STORE,
553 2,
554 1,
555 getEncAlignPower(0),
556 Terminator,
557 3,
558 naclbitc::FUNC_CODE_INST_RET,
559 1,
560 Terminator,
561 0,
562 naclbitc::BLK_CODE_EXIT,
563 Terminator,
564 0,
565 naclbitc::BLK_CODE_EXIT,
566 Terminator};
567
568 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_STORE
569
570 // Show text when alignment is 1.
571 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords),
572 Terminator);
573 EXPECT_TRUE(DumpMunger.runTest("Good Store Alignment 1"));
574 EXPECT_EQ(" 62:4| 3: <24, 2, 1, 1> | store float %p1, "
575 "float* %p0, \n",
576 DumpMunger.getLinesWithSubstring("62:4"));
577 IceTest::SubzeroBitcodeMunger Munger(
578 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator);
579 EXPECT_TRUE(Munger.runTest());
580
581 // Show what happens when changing alignment to 0.
582 const uint64_t Align0[] = {
583 ReplaceIndex,
584 NaClMungedBitcode::Replace,
585 3,
586 naclbitc::FUNC_CODE_INST_STORE,
587 2,
588 1,
589 getEncAlignZero(),
590 Terminator,
591 };
592 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
593 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n",
594 Munger.getTestResults());
595 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
596 EXPECT_EQ(
597 " store float %p1, float* %p0, align 0;\n"
598 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
599 DumpMunger.getLinesWithSubstring("store"));
600
601 // Show what happens when changing alignment to 4.
602 const uint64_t Align4[] = {
603 ReplaceIndex,
604 NaClMungedBitcode::Replace,
605 3,
606 naclbitc::FUNC_CODE_INST_STORE,
607 2,
608 1,
609 getEncAlignPower(2),
610 Terminator,
611 };
612 EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
613 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
614
615 // Show what happens when changing alignment to 8.
616 const uint64_t Align8[] = {
617 ReplaceIndex,
618 NaClMungedBitcode::Replace,
619 3,
620 naclbitc::FUNC_CODE_INST_STORE,
621 2,
622 1,
623 getEncAlignPower(3),
624 Terminator,
625 };
626 EXPECT_FALSE(Munger.runTest(ARRAY(Align8), ParseError));
627 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n",
628 Munger.getTestResults());
629 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align8)));
630 EXPECT_EQ(
631 " store float %p1, float* %p0, align 8;\n"
632 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
633 DumpMunger.getLinesWithSubstring("store"));
634
635 // Show what happens when changing alignment to 2**29.
636 const uint64_t Align29[] = {
637 ReplaceIndex,
638 NaClMungedBitcode::Replace,
639 3,
640 naclbitc::FUNC_CODE_INST_STORE,
641 2,
642 1,
643 getEncAlignPower(29),
644 Terminator,
645 };
646 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
647 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n",
648 Munger.getTestResults());
649 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
650 EXPECT_EQ(
651 " store float %p1, float* %p0, align 536870912;\n"
652 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
653 DumpMunger.getLinesWithSubstring("store"));
654
655 const uint64_t Align30[] = {
656 ReplaceIndex,
657 NaClMungedBitcode::Replace,
658 // Note: alignment stored as 0 or log2(Alignment)+1.
659 3,
660 naclbitc::FUNC_CODE_INST_STORE,
661 2,
662 1,
663 getEncAlignPower(30),
664 Terminator,
665 };
666 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
667 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n",
668 Munger.getTestResults());
669 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
670 EXPECT_EQ(
671 " store float %p1, float* %p0, align 0;\n"
672 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n",
673 DumpMunger.getLinesWithSubstring("store"));
674 }
675
676 } // end of anonymous namespace
677