Home | History | Annotate | Download | only in unittest
      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.
     32 uint64_t getEncAlignPower(unsigned Power) {
     33   return Power + 1;
     34 }
     35 uint64_t getEncAlignZero() { return 0; }
     36 
     37 /// Test how we report a call arg that refers to nonexistent call argument
     38 TEST(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, 3, Terminator,
     48     3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3, Terminator,
     49     1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
     50     3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
     51       // Note: 100 is a bad value index in next line.
     52     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 
     58   // Show bitcode objdump for BitcodeRecords.
     59   NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
     60   EXPECT_FALSE(DumpMunger.runTest());
     61   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"));
     65 
     66   // Show that we get appropriate error when parsing in Subzero.
     67   IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
     68   EXPECT_FALSE(Munger.runTest(ParseError));
     69   EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n",
     70             Munger.getTestResults());
     71 
     72   // Show that we generate a fatal error when not allowing error recovery.
     73   Ice::ClFlags::Flags.setAllowErrorRecovery(false);
     74   EXPECT_DEATH(Munger.runTest(ParseError), ".*ERROR: Unable to continue.*");
     75 }
     76 
     77 /// Test how we recognize alignments in alloca instructions.
     78 TEST(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, 3, 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.
     99   NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
    100   EXPECT_TRUE(DumpMunger.runTest());
    101   EXPECT_EQ("      62:4|    3: <19, 1, 1>            |    %v0 = alloca i8, i32 "
    102             "%p0, align 1;\n",
    103             DumpMunger.getLinesWithSubstring("62:4"));
    104 
    105   // Show that we can handle alignment of 1.
    106   IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
    107   EXPECT_TRUE(Munger.runTest());
    108 
    109   // Show what happens when changing alignment to 0.
    110   const uint64_t Align0[] = {
    111       ReplaceIndex, NaClMungedBitcode::Replace,
    112       3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignZero(), Terminator,
    113   };
    114   EXPECT_TRUE(Munger.runTest(ARRAY(Align0)));
    115   EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
    116   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[] = {
    121       ReplaceIndex, NaClMungedBitcode::Replace,
    122       3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(30), Terminator,
    123   };
    124   EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
    125   EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n",
    126             Munger.getTestResults());
    127 
    128   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
    129   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[] = {
    137       ReplaceIndex, NaClMungedBitcode::Replace,
    138       3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(29), Terminator,
    139   };
    140   EXPECT_TRUE(Munger.runTest(ARRAY(Align29)));
    141   EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
    142   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.
    147 TEST(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, 3, 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.
    166   NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
    167   EXPECT_TRUE(DumpMunger.runTest());
    168   EXPECT_EQ("      58:4|    3: <20, 1, 1, 0>         |    %v0 = load i32* %p0, "
    169             "align 1;\n",
    170             DumpMunger.getLinesWithSubstring("58:4"));
    171   IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
    172   EXPECT_TRUE(Munger.runTest());
    173 
    174   // Show what happens when changing alignment to 0.
    175   const uint64_t Align0[] = {
    176       ReplaceIndex, NaClMungedBitcode::Replace,
    177       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator,
    178   };
    179   EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
    180   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
    181             Munger.getTestResults());
    182   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
    183   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[] = {
    189       ReplaceIndex, NaClMungedBitcode::Replace,
    190       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator,
    191   };
    192   EXPECT_FALSE(Munger.runTest(ARRAY(Align4), ParseError));
    193   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n",
    194             Munger.getTestResults());
    195   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
    196   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[] = {
    202       ReplaceIndex, NaClMungedBitcode::Replace,
    203       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator,
    204   };
    205   EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
    206   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
    207             Munger.getTestResults());
    208   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
    209   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[] = {
    215       ReplaceIndex, NaClMungedBitcode::Replace,
    216       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator,
    217   };
    218   EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
    219   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
    220             Munger.getTestResults());
    221   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
    222   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.
    228 TEST(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, 3, 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.
    248   NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords));
    249   EXPECT_TRUE(DumpMunger.runTest());
    250   EXPECT_EQ("      58:4|    3: <20, 1, 1, 0>         |    %v0 = load float* "
    251             "%p0, align 1;\n",
    252             DumpMunger.getLinesWithSubstring("58:4"));
    253   IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
    254   EXPECT_TRUE(Munger.runTest());
    255 
    256   // Show what happens when changing alignment to 0.
    257   const uint64_t Align0[] = {
    258       ReplaceIndex, NaClMungedBitcode::Replace,
    259       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator,
    260   };
    261   EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
    262   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
    263             Munger.getTestResults());
    264   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
    265   EXPECT_EQ(
    266       "    %v0 = load float* %p0, align 0;\n"
    267             "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
    268             DumpMunger.getLinesWithSubstring("load"));
    269 
    270   // Show what happens when changing alignment to 4.
    271   const uint64_t Align4[] = {
    272       ReplaceIndex, NaClMungedBitcode::Replace,
    273       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator,
    274   };
    275   EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
    276   EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
    277   EXPECT_EQ("    %v0 = load float* %p0, align 4;\n",
    278             DumpMunger.getLinesWithSubstring("load"));
    279 
    280   const uint64_t Align29[] = {
    281       ReplaceIndex, NaClMungedBitcode::Replace,
    282       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator,
    283   };
    284   EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
    285   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
    286             Munger.getTestResults());
    287   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
    288   EXPECT_EQ(
    289       "    %v0 = load float* %p0, align 536870912;\n"
    290             "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
    291             DumpMunger.getLinesWithSubstring("load"));
    292 
    293   // Show what happens when changing alignment to 2**30.
    294   const uint64_t Align30[] = {
    295       ReplaceIndex, NaClMungedBitcode::Replace,
    296       3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator,
    297   };
    298   EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
    299   EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
    300             Munger.getTestResults());
    301   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
    302   EXPECT_EQ(
    303       "    %v0 = load float* %p0, align 0;\n"
    304             "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n",
    305             DumpMunger.getLinesWithSubstring("load"));
    306 }
    307 
    308 // Test how we recognize alignments in store instructions.
    309 TEST(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, 3, 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);
    331   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"));
    335   IceTest::SubzeroBitcodeMunger Munger(
    336       BitcodeRecords, array_lengthof(BitcodeRecords), Terminator);
    337   EXPECT_TRUE(Munger.runTest());
    338 
    339   // Show what happens when changing alignment to 0.
    340   const uint64_t Align0[] = {
    341       ReplaceIndex, NaClMungedBitcode::Replace,
    342       3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignZero(), Terminator,
    343   };
    344   EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError));
    345   EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n",
    346             Munger.getTestResults());
    347   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0)));
    348   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[] = {
    355       ReplaceIndex, NaClMungedBitcode::Replace,
    356       3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(2), Terminator,
    357   };
    358   EXPECT_TRUE(Munger.runTest(ARRAY(Align4)));
    359   EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4)));
    360 
    361   // Show what happens when changing alignment to 8.
    362   const uint64_t Align8[] = {
    363       ReplaceIndex, NaClMungedBitcode::Replace,
    364       3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(3), Terminator,
    365   };
    366   EXPECT_FALSE(Munger.runTest(ARRAY(Align8), ParseError));
    367   EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n",
    368             Munger.getTestResults());
    369   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align8)));
    370   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[] = {
    377       ReplaceIndex, NaClMungedBitcode::Replace,
    378       3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(29), Terminator,
    379   };
    380   EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError));
    381   EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n",
    382             Munger.getTestResults());
    383   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29)));
    384   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[] = {
    390       ReplaceIndex, NaClMungedBitcode::Replace,
    391       // Note: alignment stored as 0 or log2(Alignment)+1.
    392       3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(30), Terminator,
    393   };
    394   EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError));
    395   EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n",
    396             Munger.getTestResults());
    397   EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30)));
    398   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 
    404 } // end of anonymous namespace
    405