From 55a421f98dbaa5ef179323bc4c78e601adf745e4 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 16 Jul 2014 01:34:27 +0000 Subject: [PATCH] Roundtrip the inalloca bit on allocas through bitcode This was an oversight in the original support. As it is, I stuffed this bit into the alignment. The alignment is stored in log2 form, so it doesn't need more than 5 bits, given that Value::MaximumAlignment is 1 << 29. Reviewers: nicholas Differential Revision: http://reviews.llvm.org/D3943 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213118 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/LLVMBitCodes.h | 2 +- lib/Bitcode/Reader/BitcodeReader.cpp | 8 ++++++-- lib/Bitcode/Writer/BitcodeWriter.cpp | 11 +++++++++-- test/Bitcode/inalloca.ll | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 test/Bitcode/inalloca.ll diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index f7e30ef1e9c..75b26a94c9b 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -290,7 +290,7 @@ namespace bitc { FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] // 17 is unused. // 18 is unused. - FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align] + FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, opty, op, align] FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] // 21 is unused. // 22 is unused. diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 192f7538da8..e7de539a325 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2889,10 +2889,14 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { dyn_cast_or_null(getTypeByID(Record[0])); Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); - unsigned Align = Record[3]; + unsigned AlignRecord = Record[3]; + bool InAlloca = AlignRecord & (1 << 5); + unsigned Align = AlignRecord & ((1 << 5) - 1); if (!Ty || !Size) return Error(InvalidRecord); - I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); + AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); + AI->setUsedWithInAlloca(InAlloca); + I = AI; InstructionList.push_back(I); break; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index dd9282a09e8..d5c7968b157 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1431,13 +1431,20 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; } - case Instruction::Alloca: + case Instruction::Alloca: { Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); Vals.push_back(VE.getValueID(I.getOperand(0))); // size. - Vals.push_back(Log2_32(cast(I).getAlignment())+1); + const AllocaInst &AI = cast(I); + unsigned AlignRecord = Log2_32(AI.getAlignment()) + 1; + assert(Log2_32(Value::MaximumAlignment) + 1 < 1 << 5 && + "not enough bits for maximum alignment"); + assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64"); + AlignRecord |= AI.isUsedWithInAlloca() << 5; + Vals.push_back(AlignRecord); break; + } case Instruction::Load: if (cast(I).isAtomic()) { diff --git a/test/Bitcode/inalloca.ll b/test/Bitcode/inalloca.ll new file mode 100644 index 00000000000..bad87a9b03f --- /dev/null +++ b/test/Bitcode/inalloca.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +; inalloca should roundtrip. + +define void @foo(i32* inalloca %args) { + ret void +} +; CHECK-LABEL: define void @foo(i32* inalloca %args) + +define void @bar() { + ; Use the maximum alignment, since we stuff our bit with alignment. + %args = alloca inalloca i32, align 536870912 + call void @foo(i32* inalloca %args) + ret void +} +; CHECK-LABEL: define void @bar() { +; CHECK: %args = alloca inalloca i32, align 536870912 +; CHECK: call void @foo(i32* inalloca %args) -- 2.34.1