diff options
-rw-r--r-- | docs/PNaClLangRef.rst | 6 | ||||
-rw-r--r-- | lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp | 6 | ||||
-rw-r--r-- | lib/Transforms/NaCl/ReplacePtrsWithInts.cpp | 19 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-stripped-pointers.ll | 9 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/instructions.ll | 2 | ||||
-rw-r--r-- | test/Transforms/NaCl/replace-ptrs-with-ints.ll | 41 |
6 files changed, 53 insertions, 30 deletions
diff --git a/docs/PNaClLangRef.rst b/docs/PNaClLangRef.rst index 4333bbc77f..45895f499b 100644 --- a/docs/PNaClLangRef.rst +++ b/docs/PNaClLangRef.rst @@ -271,12 +271,12 @@ Only the LLVM instructions listed here are supported by PNaCl bitcode. * ``frem`` * ``alloca`` - The only allowed type for ``alloca`` instructions in PNaCl bitcode is an - array of i8. For example: + The only allowed type for ``alloca`` instructions in PNaCl bitcode + is i8. For example: .. code-block:: llvm - %buf = alloca [4 x i8], align 1 + %buf = alloca i8, i32 8, align 4 * ``load``, ``store`` diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp index a090bdd9a9..1fe79757a0 100644 --- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp +++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp @@ -290,10 +290,8 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { break; case Instruction::Alloca: { - ArrayType *Ty = dyn_cast<ArrayType>(cast<AllocaInst>(Inst) - ->getType()->getElementType()); - if (!Ty || !Ty->getElementType()->isIntegerTy(8)) - return "non-i8-array alloca"; + if (!cast<AllocaInst>(Inst)->getAllocatedType()->isIntegerTy(8)) + return "non-i8 alloca"; break; } diff --git a/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp b/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp index 03d42e072c..c812f4d432 100644 --- a/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp +++ b/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp @@ -17,7 +17,7 @@ // All inttoptr and ptrtoint instructions use the same integer size // (iPTR), so they do not implicitly truncate or zero-extend. // -// alloca always allocates an i8 array type. +// alloca always has the result type i8*. // // Pointer types only appear in the following instructions: // * loads and stores: the pointer operand is a NormalizedPtr. @@ -470,13 +470,22 @@ static void ConvertInstruction(DataLayout *DL, Type *IntPtrType, FC->recordConvertedAndErase(Call, NewCall); } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) { Type *ElementTy = Inst->getType()->getPointerElementType(); - Type *ElementTy2 = ArrayType::get(Type::getInt8Ty(Inst->getContext()), - DL->getTypeAllocSize(ElementTy)); + Constant *ElementSize = ConstantInt::get(IntPtrType, + DL->getTypeAllocSize(ElementTy)); + // Expand out alloca's built-in multiplication. + Value *MulSize; + if (ConstantInt *C = dyn_cast<ConstantInt>(Alloca->getArraySize())) { + MulSize = ConstantExpr::getMul(ElementSize, C); + } else { + MulSize = BinaryOperator::Create( + Instruction::Mul, ElementSize, Alloca->getArraySize(), + Alloca->getName() + ".alloca_mul", Alloca); + } unsigned Alignment = Alloca->getAlignment(); if (Alignment == 0) Alignment = DL->getPrefTypeAlignment(ElementTy); - Value *Tmp = CopyDebug(new AllocaInst(ElementTy2, Alloca->getArraySize(), - Alignment, "", Inst), + Value *Tmp = CopyDebug(new AllocaInst(Type::getInt8Ty(Inst->getContext()), + MulSize, Alignment, "", Inst), Inst); Tmp->takeName(Alloca); Value *Alloca2 = new PtrToIntInst(Tmp, IntPtrType, diff --git a/test/NaCl/PNaClABI/abi-stripped-pointers.ll b/test/NaCl/PNaClABI/abi-stripped-pointers.ll index d590d4902d..07516fb290 100644 --- a/test/NaCl/PNaClABI/abi-stripped-pointers.ll +++ b/test/NaCl/PNaClABI/abi-stripped-pointers.ll @@ -34,8 +34,9 @@ define void @allowed_cases(i32 %arg) { ptrtoint [4 x i8]* @var to i32 - %alloc = alloca [1 x i8] - ptrtoint [1 x i8]* %alloc to i32 + %alloc = alloca i8 + ptrtoint i8* %alloc to i32 + load i8* %alloc, align 1 ; These instructions may use a NormalizedPtr, which may be a global. load i32* @ptr, align 1 @@ -83,7 +84,9 @@ entry: ; CHECK-NEXT: non-i32 inttoptr %a = alloca i32 -; CHECK-NEXT: non-i8-array alloca +; CHECK-NEXT: non-i8 alloca: %a + %a2 = alloca [4 x i8] +; CHECK-NEXT: non-i8 alloca: %a2 store i32 0, i32* null, align 1 ; CHECK-NEXT: bad pointer diff --git a/test/NaCl/PNaClABI/instructions.ll b/test/NaCl/PNaClABI/instructions.ll index 11b344e5a7..49e8df5126 100644 --- a/test/NaCl/PNaClABI/instructions.ll +++ b/test/NaCl/PNaClABI/instructions.ll @@ -71,7 +71,7 @@ define void @aggregates() { define void @memory() { ; Memory operations - %a1 = alloca [4 x i8] + %a1 = alloca i8, i32 4 %ptr = inttoptr i32 0 to i32* %a2 = load i32* %ptr, align 1 store i32 undef, i32* %ptr, align 1 diff --git a/test/Transforms/NaCl/replace-ptrs-with-ints.ll b/test/Transforms/NaCl/replace-ptrs-with-ints.ll index 823697d738..7761661798 100644 --- a/test/Transforms/NaCl/replace-ptrs-with-ints.ll +++ b/test/Transforms/NaCl/replace-ptrs-with-ints.ll @@ -352,8 +352,20 @@ define void @alloca_fixed() { ret void } ; CHECK: define void @alloca_fixed() { -; CHECK-NEXT: %buf = alloca [8 x i8], align 128 -; CHECK-NEXT: %buf.asint = ptrtoint [8 x i8]* %buf to i32 +; CHECK-NEXT: %buf = alloca i8, i32 8, align 128 +; CHECK-NEXT: %buf.asint = ptrtoint i8* %buf to i32 +; CHECK-NEXT: call void @receive_alloca(i32 %buf.asint) + +; When the size passed to alloca is a constant, it should be a +; constant in the output too. +define void @alloca_fixed_array() { + %buf = alloca %struct, i32 100 + call void @receive_alloca(%struct* %buf) + ret void +} +; CHECK: define void @alloca_fixed_array() { +; CHECK-NEXT: %buf = alloca i8, i32 800, align 8 +; CHECK-NEXT: %buf.asint = ptrtoint i8* %buf to i32 ; CHECK-NEXT: call void @receive_alloca(i32 %buf.asint) define void @alloca_variable(i32 %size) { @@ -362,8 +374,9 @@ define void @alloca_variable(i32 %size) { ret void } ; CHECK: define void @alloca_variable(i32 %size) { -; CHECK-NEXT: %buf = alloca [8 x i8], i32 %size -; CHECK-NEXT: %buf.asint = ptrtoint [8 x i8]* %buf to i32 +; CHECK-NEXT: %buf.alloca_mul = mul i32 8, %size +; CHECK-NEXT: %buf = alloca i8, i32 %buf.alloca_mul +; CHECK-NEXT: %buf.asint = ptrtoint i8* %buf to i32 ; CHECK-NEXT: call void @receive_alloca(i32 %buf.asint) define void @alloca_alignment_i32() { @@ -371,21 +384,21 @@ define void @alloca_alignment_i32() { ret void } ; CHECK: void @alloca_alignment_i32() { -; CHECK-NEXT: alloca [4 x i8], align 4 +; CHECK-NEXT: alloca i8, i32 4, align 4 define void @alloca_alignment_double() { %buf = alloca double ret void } ; CHECK: void @alloca_alignment_double() { -; CHECK-NEXT: alloca [8 x i8], align 8 +; CHECK-NEXT: alloca i8, i32 8, align 8 define void @alloca_lower_alignment() { %buf = alloca i32, align 1 ret void } ; CHECK: void @alloca_lower_alignment() { -; CHECK-NEXT: alloca [4 x i8], align 1 +; CHECK-NEXT: alloca i8, i32 4, align 1 ; This tests for a bug in which, when processing the store's %buf2 @@ -400,8 +413,8 @@ define void @alloca_cast_stripping() { ret void } ; CHECK: define void @alloca_cast_stripping() { -; CHECK-NEXT: %buf = alloca [4 x i8] -; CHECK-NEXT: %buf.bc = bitcast [4 x i8]* %buf to i32* +; CHECK-NEXT: %buf = alloca i8, i32 4 +; CHECK-NEXT: %buf.bc = bitcast i8* %buf to i32* ; CHECK-NEXT: store i32 0, i32* %buf.bc @@ -449,8 +462,8 @@ define void @debug_declare(i32 %val) { ret void } ; CHECK: define void @debug_declare(i32 %val) { -; CHECK-NEXT: %var = alloca [4 x i8] -; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{[4 x i8]* %var}, metadata !0) +; CHECK-NEXT: %var = alloca i8, i32 4 +; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{i8* %var}, metadata !0) ; This case is currently not converted. ; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{null}, metadata !0) ; CHECK-NEXT: ret void @@ -498,7 +511,7 @@ define void @alloca_lifetime() { ret void } ; CHECK: define void @alloca_lifetime() { -; CHECK-NEXT: %buf = alloca [1 x i8] +; CHECK-NEXT: %buf = alloca i8 ; CHECK-NEXT: ret void define void @alloca_lifetime_via_bitcast() { @@ -508,7 +521,7 @@ define void @alloca_lifetime_via_bitcast() { ret void } ; CHECK: define void @alloca_lifetime_via_bitcast() { -; CHECK-NEXT: %buf = alloca [4 x i8] +; CHECK-NEXT: %buf = alloca i8, i32 4 ; CHECK-NEXT: ret void define void @strip_invariant_markers() { @@ -518,7 +531,7 @@ define void @strip_invariant_markers() { ret void } ; CHECK: define void @strip_invariant_markers() { -; CHECK-NEXT: %buf = alloca [1 x i8] +; CHECK-NEXT: %buf = alloca i8 ; CHECK-NEXT: ret void |