aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2014-02-12 18:09:29 -0800
committerDan Gohman <sunfish@google.com>2014-02-12 22:30:21 -0800
commit2b36da6f5426d0ea67c85fdee8016a5bbc828a23 (patch)
treeefcca323596c1b5d4a73a6e1d999ee3a036c3875
parentefc65c9a54d6bd6f20bed5cc19b058aa1d7c3a3a (diff)
Generalize PromoteIntegers to handle arbitrary bit widths.
-rw-r--r--lib/Transforms/NaCl/PromoteIntegers.cpp26
-rw-r--r--test/Transforms/NaCl/promote-integers.ll48
2 files changed, 74 insertions, 0 deletions
diff --git a/lib/Transforms/NaCl/PromoteIntegers.cpp b/lib/Transforms/NaCl/PromoteIntegers.cpp
index 5c910d21c1..f12bc883c6 100644
--- a/lib/Transforms/NaCl/PromoteIntegers.cpp
+++ b/lib/Transforms/NaCl/PromoteIntegers.cpp
@@ -64,13 +64,19 @@ INITIALIZE_PASS(PromoteIntegers, "nacl-promote-ints",
// There are currently none in our tests that use the ABI checker.
// See https://code.google.com/p/nativeclient/issues/detail?id=3360
static bool isLegalSize(unsigned Size) {
+#if 0 // XXX EMSCRIPTEN: Generalize this code to work on any bit width.
if (Size > 64) return true;
return Size == 1 || Size == 8 || Size == 16 || Size == 32 || Size == 64;
+#else
+ return Size == 1 || (Size >= 8 && isPowerOf2_32(Size));
+#endif
}
static Type *getPromotedIntType(IntegerType *Ty) {
unsigned Width = Ty->getBitWidth();
+#if 0 // XXX EMSCRIPTEN: We support promoting these types to power-of-2 sizes.
assert(Width <= 64 && "Don't know how to legalize >64 bit types yet");
+#endif
if (isLegalSize(Width))
return Ty;
return IntegerType::get(Ty->getContext(),
@@ -110,10 +116,17 @@ static Value *convertConstant(Constant *C, bool SignExt=false) {
if (isa<UndefValue>(C)) {
return UndefValue::get(getPromotedType(C->getType()));
} else if (ConstantInt *CInt = dyn_cast<ConstantInt>(C)) {
+#if 0 // XXX EMSCRIPTEN: Generalize this code to work on any bit width.
return ConstantInt::get(
getPromotedType(C->getType()),
SignExt ? CInt->getSExtValue() : CInt->getZExtValue(),
/*isSigned=*/SignExt);
+#else
+ unsigned BitWidth = getPromotedType(C->getType())->getIntegerBitWidth();
+ const APInt &Value = CInt->getValue();
+ return ConstantInt::get(C->getContext(),
+ SignExt ? Value.sext(BitWidth) : Value.zext(BitWidth));
+#endif
} else {
errs() << "Value: " << *C << "\n";
report_fatal_error("Unexpected constant value");
@@ -293,13 +306,26 @@ static Value *splitStore(StoreInst *Inst, ConversionState &State) {
if (!isLegalSize(Width - LoWidth)) {
// HiTrunc is still illegal, and is redundant with the truncate in the
// recursive call, so just get rid of it.
+#if 0 /// XXX EMSCRIPTEN: Allow these to be ConstantExprs
State.recordConverted(cast<Instruction>(HiTrunc), HiLShr,
/*TakeName=*/false);
+#else
+ if (Instruction *HiTruncInst = dyn_cast<Instruction>(HiTrunc)) {
+ State.recordConverted(HiTruncInst, HiLShr,
+ /*TakeName=*/false);
+ }
+#endif
StoreHi = splitStore(cast<StoreInst>(StoreHi), State);
// BCHi was still illegal, and has been replaced with a placeholder in the
// recursive call. Since it is redundant with BCLo in the recursive call,
// just splice it out entirely.
+#if 0 /// XXX EMSCRIPTEN: Allow these to be ConstantExprs
State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false);
+#else
+ if (Instruction *BCHiInst = dyn_cast<Instruction>(BCHi)) {
+ State.recordConverted(BCHiInst, GEPHi, /*TakeName=*/false);
+ }
+#endif
}
State.recordConverted(Inst, StoreHi, /*TakeName=*/false);
return StoreHi;
diff --git a/test/Transforms/NaCl/promote-integers.ll b/test/Transforms/NaCl/promote-integers.ll
index 1067e25fd5..7c010be32b 100644
--- a/test/Transforms/NaCl/promote-integers.ll
+++ b/test/Transforms/NaCl/promote-integers.ll
@@ -398,3 +398,51 @@ if2:
end:
ret void
}
+
+; CHECK: @bigger_integers
+; CHECK-NEXT: %q = bitcast i8* %p to i128*
+; CHECK-NEXT: %q.loty = bitcast i128* %q to i64*
+; CHECK-NEXT: %x.lo = load i64* %q.loty
+; CHECK-NEXT: %x.lo.ext = zext i64 %x.lo to i128
+; CHECK-NEXT: %q.hi = getelementptr i64* %q.loty, i32 1
+; CHECK-NEXT: %q.hity.loty = bitcast i64* %q.hi to i32*
+; CHECK-NEXT: %x.hi.lo = load i32* %q.hity.loty
+; CHECK-NEXT: %x.hi.lo.ext = zext i32 %x.hi.lo to i64
+; CHECK-NEXT: %q.hity.hi = getelementptr i32* %q.hity.loty, i32 1
+; CHECK-NEXT: %q.hity.hity.loty = bitcast i32* %q.hity.hi to i16*
+; CHECK-NEXT: %x.hi.hi.lo = load i16* %q.hity.hity.loty
+; CHECK-NEXT: %x.hi.hi.lo.ext = zext i16 %x.hi.hi.lo to i32
+; CHECK-NEXT: %q.hity.hity.hi = getelementptr i16* %q.hity.hity.loty, i32 1
+; CHECK-NEXT: %q.hity.hity.hity = bitcast i16* %q.hity.hity.hi to i8*
+; CHECK-NEXT: %x.hi.hi.hi = load i8* %q.hity.hity.hity
+; CHECK-NEXT: %x.hi.hi.hi.ext = zext i8 %x.hi.hi.hi to i32
+; CHECK-NEXT: %x.hi.hi.hi.ext.sh = shl i32 %x.hi.hi.hi.ext, 16
+; CHECK-NEXT: %x.hi.hi = or i32 %x.hi.hi.lo.ext, %x.hi.hi.hi.ext.sh
+; CHECK-NEXT: %x.hi.hi.ext = zext i32 %x.hi.hi to i64
+; CHECK-NEXT: %x.hi.hi.ext.sh = shl i64 %x.hi.hi.ext, 32
+; CHECK-NEXT: %x.hi = or i64 %x.hi.lo.ext, %x.hi.hi.ext.sh
+; CHECK-NEXT: %x.hi.ext = zext i64 %x.hi to i128
+; CHECK-NEXT: %x.hi.ext.sh = shl i128 %x.hi.ext, 64
+; CHECK-NEXT: %x = or i128 %x.lo.ext, %x.hi.ext.sh
+; CHECK-NEXT: %q.loty1 = bitcast i128* %q to i64*
+; CHECK-NEXT: store i64 -5076944270305263616, i64* %q.loty1
+; CHECK-NEXT: %q.hi2 = getelementptr i64* %q.loty1, i32 1
+; CHECK-NEXT: %q.hity3.loty = bitcast i64* %q.hi2 to i32*
+; CHECK-NEXT: store i32 1624466223, i32* %q.hity3.loty, align 1
+; CHECK-NEXT: %q.hity3.hi = getelementptr i32* %q.hity3.loty, i32 1
+; CHECK-NEXT: %q.hity3.hity.loty = bitcast i32* %q.hity3.hi to i16*
+; CHECK-NEXT: store i16 3, i16* %q.hity3.hity.loty, align 1
+; CHECK-NEXT: %q.hity3.hity.hi = getelementptr i16* %q.hity3.hity.loty, i32 1
+; CHECK-NEXT: %q.hity3.hity.hity = bitcast i16* %q.hity3.hity.hi to i8*
+; CHECK-NEXT: store i8 0, i8* %q.hity3.hity.hity
+; CHECK-NEXT: %z = add i128 %x, 3
+; CHECK-NEXT: %y = trunc i128 %z to i32
+; CHECK-NEXT: ret i32 %y
+define i32 @bigger_integers(i8* %p) {
+ %q = bitcast i8* %p to i120*
+ %x = load i120* %q
+ store i120 267650600228229401496703205376, i120* %q
+ %z = add i120 %x, 3
+ %y = trunc i120 %z to i32
+ ret i32 %y
+}