aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/PNaClLangRef.rst6
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp6
-rw-r--r--lib/Transforms/NaCl/ReplacePtrsWithInts.cpp19
-rw-r--r--test/NaCl/PNaClABI/abi-stripped-pointers.ll9
-rw-r--r--test/NaCl/PNaClABI/instructions.ll2
-rw-r--r--test/Transforms/NaCl/replace-ptrs-with-ints.ll41
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