You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
27 KiB
677 lines
27 KiB
//===- 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 <string>
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
|
|
#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
|
|
#pragma clang diagnostic pop
|
|
|
|
#include "BitcodeMunge.h"
|
|
#include "unittests/Bitcode/NaClMungeTest.h"
|
|
|
|
using namespace llvm;
|
|
using namespace naclmungetest;
|
|
|
|
namespace {
|
|
|
|
// The ParseError constant is passed to the BitcodeMunger to prevent translation
|
|
// when we expect a Parse error.
|
|
constexpr bool ParseError = true;
|
|
|
|
// 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, 3, Terminator, 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3,
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_FALSE(DumpMunger.runTest());
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_FALSE(Munger.runTest(ParseError));
|
|
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.
|
|
Ice::ClFlags::Flags.setAllowErrorRecovery(false);
|
|
EXPECT_DEATH(Munger.runTest(ParseError), ".*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,
|
|
3,
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(DumpMunger.runTest());
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(Munger.runTest());
|
|
|
|
// 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(ARRAY(Align0)));
|
|
EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align30), ParseError));
|
|
EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n",
|
|
Munger.getTestResults());
|
|
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align29)));
|
|
EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(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,
|
|
3,
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(DumpMunger.runTest());
|
|
EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load i32* %p0, "
|
|
"align 1;\n",
|
|
DumpMunger.getLinesWithSubstring("58:4"));
|
|
IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(Munger.runTest());
|
|
|
|
// 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(ARRAY(Align0), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align4), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align29), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align30), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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,
|
|
3,
|
|
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(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(DumpMunger.runTest());
|
|
EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load float* "
|
|
"%p0, align 1;\n",
|
|
DumpMunger.getLinesWithSubstring("58:4"));
|
|
IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
|
|
EXPECT_TRUE(Munger.runTest());
|
|
|
|
// 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(ARRAY(Align0), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align4)));
|
|
EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align29), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align30), ParseError));
|
|
EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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,
|
|
3,
|
|
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());
|
|
|
|
// 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(ARRAY(Align0), ParseError));
|
|
EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align4)));
|
|
EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align8), ParseError));
|
|
EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align29), ParseError));
|
|
EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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(ARRAY(Align30), ParseError));
|
|
EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n",
|
|
Munger.getTestResults());
|
|
EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(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
|