• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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