| //===- unittest/IceParseInstsTest.cpp - test instruction errors -----------===// |
| // |
| // The Subzero Code Generator |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/ADT/STLExtras.h" |
| #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
| #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
| |
| #include "BitcodeMunge.h" |
| |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| static const uint64_t Terminator = 0x5768798008978675LL; |
| |
| // Note: alignment stored as 0 or log2(Alignment)+1. |
| uint64_t getEncAlignPower(unsigned Power) { |
| return Power + 1; |
| } |
| uint64_t getEncAlignZero() { return 0; } |
| |
| /// Test how we report a call arg that refers to nonexistent call argument |
| TEST(IceParseInstsTest, NonexistentCallArg) { |
| const uint64_t BitcodeRecords[] = { |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 3, naclbitc::TYPE_CODE_VOID, Terminator, |
| 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 1, 0, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| // Note: 100 is a bad value index in next line. |
| 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_RET, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator |
| }; |
| |
| // Show bitcode objdump for BitcodeRecords. |
| NaClObjDumpMunger DumpMunger(BitcodeRecords, |
| array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_FALSE(DumpMunger.runTest("Nonexistent call arg")); |
| EXPECT_EQ(" 66:4| 3: <34, 0, 4, 2, 100> | call void @f0(i32 " |
| "%p0, i32 @f0);\n" |
| "Error(66:4): Invalid relative value id: 100 (Must be <= 4)\n", |
| DumpMunger.getLinesWithSubstring("66:4")); |
| |
| // Show that we get appropriate error when parsing in Subzero. |
| IceTest::SubzeroBitcodeMunger Munger( |
| BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_FALSE(Munger.runTest("Nonexistent call arg")); |
| EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n", |
| Munger.getTestResults()); |
| |
| // Show that we generate a fatal error when not allowing error recovery. |
| Munger.Flags.setAllowErrorRecovery(false); |
| EXPECT_DEATH( |
| Munger.runTest("Nonexistent call arg"), |
| ".*ERROR: Unable to continue.*"); |
| } |
| |
| /// Test how we recognize alignments in alloca instructions. |
| TEST(IceParseInstsTests, AllocaAlignment) { |
| const uint64_t BitcodeRecords[] = { |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_NUMENTRY, 4, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 3, naclbitc::TYPE_CODE_VOID, Terminator, |
| 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 8, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(0), Terminator, |
| 3, naclbitc::FUNC_CODE_INST_RET, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| |
| const uint64_t ReplaceIndex = 11; // index for FUNC_CODE_INST_ALLOCA |
| |
| // Show text when alignment is 1. |
| NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| Terminator); |
| EXPECT_TRUE(DumpMunger.runTest("Good alloca alignment 1")); |
| EXPECT_EQ(" 62:4| 3: <19, 1, 1> | %v0 = alloca i8, i32 " |
| "%p0, align 1;\n", |
| DumpMunger.getLinesWithSubstring("62:4")); |
| |
| // Show that we can handle alignment of 1. |
| IceTest::SubzeroBitcodeMunger Munger( |
| BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_TRUE(Munger.runTest("Good alloca alignment 1")); |
| |
| // Show what happens when changing alignment to 0. |
| const uint64_t Align0[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignZero(), Terminator, |
| }; |
| EXPECT_TRUE(Munger.runTest("Good alloca alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_TRUE(DumpMunger.runTestForAssembly("Good alloca alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", |
| DumpMunger.getLinesWithSubstring("alloca")); |
| |
| // Show what happens when changing alignment to 2**30. |
| const uint64_t Align30[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(30), Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad alloca alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n", |
| Munger.getTestResults()); |
| |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad alloca alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", |
| DumpMunger.getLinesWithSubstring("alloca")); |
| EXPECT_EQ( |
| "Error(62:4): Alignment can't be greater than 2**29. Found: 2**30\n", |
| DumpMunger.getLinesWithSubstring("Error")); |
| |
| // Show what happens when changing alignment to 2**29. |
| const uint64_t Align29[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(29), Terminator, |
| }; |
| EXPECT_TRUE(Munger.runTest("Good alloca alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_TRUE(DumpMunger.runTestForAssembly("Good alloca alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 536870912;\n", |
| DumpMunger.getLinesWithSubstring("alloca")); |
| } |
| |
| // Test how we recognize alignments in load i32 instructions. |
| TEST(IceParseInstsTests, LoadI32Alignment) { |
| const uint64_t BitcodeRecords[] = { |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_NUMENTRY, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 0, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| |
| const uint64_t ReplaceIndex = 9; // index for FUNC_CODE_INST_LOAD |
| |
| // Show text when alignment is 1. |
| NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| Terminator); |
| EXPECT_TRUE(DumpMunger.runTest("Good load i32 alignment 1")); |
| EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load i32* %p0, " |
| "align 1;\n", |
| DumpMunger.getLinesWithSubstring("58:4")); |
| IceTest::SubzeroBitcodeMunger Munger( |
| BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_TRUE(Munger.runTest("Good load i32 alignment 1")); |
| |
| // Show what happens when changing alignment to 0. |
| const uint64_t Align0[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" |
| "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| // Show what happens when changing alignment to 4. |
| const uint64_t Align4[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 4", Align4, |
| array_lengthof(Align4))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 4", Align4, |
| array_lengthof(Align4))); |
| EXPECT_EQ(" %v0 = load i32* %p0, align 4;\n" |
| "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| // Show what happens when changing alignment to 2**29. |
| const uint64_t Align29[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 29", |
| Align29, array_lengthof(Align29))); |
| EXPECT_EQ(" %v0 = load i32* %p0, align 536870912;\n" |
| "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| // Show what happens when changing alignment to 2**30. |
| const uint64_t Align30[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load i32 alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load i32 alignment 30", |
| Align30, array_lengthof(Align30))); |
| EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" |
| "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| } |
| |
| // Test how we recognize alignments in load float instructions. |
| TEST(IceParseInstsTests, LoadFloatAlignment) { |
| const uint64_t BitcodeRecords[] = { |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
| 3, naclbitc::TYPE_CODE_FLOAT, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| |
| const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_LOAD |
| |
| // Show text when alignment is 1. |
| NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| Terminator); |
| EXPECT_TRUE(DumpMunger.runTest("Good load float alignment 1")); |
| EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load float* " |
| "%p0, align 1;\n", |
| DumpMunger.getLinesWithSubstring("58:4")); |
| IceTest::SubzeroBitcodeMunger Munger( |
| BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_TRUE(Munger.runTest("Good load float alignment 1")); |
| |
| // Show what happens when changing alignment to 0. |
| const uint64_t Align0[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load float alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 0", |
| Align0, array_lengthof(Align0))); |
| EXPECT_EQ( |
| " %v0 = load float* %p0, align 0;\n" |
| "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| // Show what happens when changing alignment to 4. |
| const uint64_t Align4[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, |
| }; |
| EXPECT_TRUE(Munger.runTest("Good load float alignment 4", Align4, |
| array_lengthof(Align4))); |
| EXPECT_TRUE(DumpMunger.runTestForAssembly("Good load float alignment 4", |
| Align4, array_lengthof(Align4))); |
| EXPECT_EQ(" %v0 = load float* %p0, align 4;\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| const uint64_t Align29[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load float alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 29", |
| Align29, array_lengthof(Align29))); |
| EXPECT_EQ( |
| " %v0 = load float* %p0, align 536870912;\n" |
| "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| |
| // Show what happens when changing alignment to 2**30. |
| const uint64_t Align30[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad load float alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad load float alignment 30", |
| Align30, array_lengthof(Align30))); |
| EXPECT_EQ( |
| " %v0 = load float* %p0, align 0;\n" |
| "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("load")); |
| } |
| |
| // Test how we recognize alignments in store instructions. |
| TEST(NaClParseInstsTests, StoreAlignment) { |
| const uint64_t BitcodeRecords[] = { |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, |
| 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, |
| 3, naclbitc::TYPE_CODE_FLOAT, Terminator, |
| 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, |
| 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, 0, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 0, Terminator, |
| 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, |
| 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(0), Terminator, |
| 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator, |
| 0, naclbitc::BLK_CODE_EXIT, Terminator}; |
| |
| const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_STORE |
| |
| // Show text when alignment is 1. |
| NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), |
| Terminator); |
| EXPECT_TRUE(DumpMunger.runTest("Good Store Alignment 1")); |
| EXPECT_EQ(" 62:4| 3: <24, 2, 1, 1> | store float %p1, " |
| "float* %p0, \n", |
| DumpMunger.getLinesWithSubstring("62:4")); |
| IceTest::SubzeroBitcodeMunger Munger( |
| BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); |
| EXPECT_TRUE(Munger.runTest("Good store alignment")); |
| |
| // Show what happens when changing alignment to 0. |
| const uint64_t Align0[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignZero(), Terminator, |
| }; |
| EXPECT_FALSE( |
| Munger.runTest("Bad store alignment 0", Align0, array_lengthof(Align0))); |
| EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 0", Align0, |
| array_lengthof(Align0))); |
| EXPECT_EQ( |
| " store float %p1, float* %p0, align 0;\n" |
| "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("store")); |
| |
| // Show what happens when changing alignment to 4. |
| const uint64_t Align4[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(2), Terminator, |
| }; |
| EXPECT_TRUE( |
| Munger.runTest("Bad store alignment 4", Align4, array_lengthof(Align4))); |
| EXPECT_TRUE(DumpMunger.runTestForAssembly("Good store alignment 4", Align4, |
| array_lengthof(Align4))); |
| |
| // Show what happens when changing alignment to 8. |
| const uint64_t Align8[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(3), Terminator, |
| }; |
| EXPECT_FALSE( |
| Munger.runTest("Bad store alignment 8", Align8, array_lengthof(Align8))); |
| EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 8", Align8, |
| array_lengthof(Align8))); |
| EXPECT_EQ( |
| " store float %p1, float* %p0, align 8;\n" |
| "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("store")); |
| |
| // Show what happens when changing alignment to 2**29. |
| const uint64_t Align29[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(29), Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad store alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad store alignment 29", Align29, |
| array_lengthof(Align29))); |
| EXPECT_EQ( |
| " store float %p1, float* %p0, align 536870912;\n" |
| "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("store")); |
| |
| const uint64_t Align30[] = { |
| ReplaceIndex, NaClMungedBitcode::Replace, |
| // Note: alignment stored as 0 or log2(Alignment)+1. |
| 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(30), Terminator, |
| }; |
| EXPECT_FALSE(Munger.runTest("Bad store alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n", |
| Munger.getTestResults()); |
| EXPECT_FALSE(DumpMunger.runTestForAssembly("Bad Store alignment 30", Align30, |
| array_lengthof(Align30))); |
| EXPECT_EQ( |
| " store float %p1, float* %p0, align 0;\n" |
| "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", |
| DumpMunger.getLinesWithSubstring("store")); |
| } |
| |
| } // end of anonymous namespace |