diff options
author | Dan Gohman <sunfish@google.com> | 2014-02-12 18:09:29 -0800 |
---|---|---|
committer | Dan Gohman <sunfish@google.com> | 2014-02-12 22:30:21 -0800 |
commit | 2b36da6f5426d0ea67c85fdee8016a5bbc828a23 (patch) | |
tree | efcca323596c1b5d4a73a6e1d999ee3a036c3875 | |
parent | efc65c9a54d6bd6f20bed5cc19b058aa1d7c3a3a (diff) |
Generalize PromoteIntegers to handle arbitrary bit widths.
-rw-r--r-- | lib/Transforms/NaCl/PromoteIntegers.cpp | 26 | ||||
-rw-r--r-- | test/Transforms/NaCl/promote-integers.ll | 48 |
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 +} |