diff options
-rw-r--r-- | lib/Transforms/NaCl/ReplacePtrsWithInts.cpp | 20 | ||||
-rw-r--r-- | test/Transforms/NaCl/replace-ptrs-with-ints.ll | 15 |
2 files changed, 31 insertions, 4 deletions
diff --git a/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp b/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp index 9be459d986..03d42e072c 100644 --- a/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp +++ b/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp @@ -48,7 +48,6 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" -#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" @@ -373,9 +372,22 @@ static void ConvertInstruction(DataLayout *DL, Type *IntPtrType, } else if (isa<PtrToIntInst>(Inst) || isa<IntToPtrInst>(Inst)) { Value *Arg = FC->convert(Inst->getOperand(0)); Type *ResultTy = FC->convertType(Inst->getType()); - IRBuilder<> Builder(Inst); - Builder.SetCurrentDebugLocation(Inst->getDebugLoc()); - Value *Result = Builder.CreateZExtOrTrunc(Arg, ResultTy, ""); + unsigned ArgSize = Arg->getType()->getIntegerBitWidth(); + unsigned ResultSize = ResultTy->getIntegerBitWidth(); + Value *Result; + // We avoid using IRBuilder's CreateZExtOrTrunc() here because it + // constant-folds ptrtoint ConstantExprs. This leads to creating + // ptrtoints of non-IntPtrType type, which is not what we want, + // because we want truncation/extension to be done explicitly by + // separate instructions. + if (ArgSize == ResultSize) { + Result = Arg; + } else { + Instruction::CastOps CastType = + ArgSize > ResultSize ? Instruction::Trunc : Instruction::ZExt; + Result = CopyDebug(CastInst::Create(CastType, Arg, ResultTy, "", Inst), + Inst); + } if (Result != Arg) Result->takeName(Inst); FC->recordConvertedAndErase(Inst, Result); diff --git a/test/Transforms/NaCl/replace-ptrs-with-ints.ll b/test/Transforms/NaCl/replace-ptrs-with-ints.ll index d7e85f6da6..5a8f58dbaf 100644 --- a/test/Transforms/NaCl/replace-ptrs-with-ints.ll +++ b/test/Transforms/NaCl/replace-ptrs-with-ints.ll @@ -141,6 +141,21 @@ define i32* @ptrtoint_different_size(i32* %ptr) { ; CHECK-NEXT: %c = trunc i64 %b to i32 ; CHECK-NEXT: ret i32 %c +define i8 @ptrtoint_truncates_var(i32* %ptr) { + %a = ptrtoint i32* %ptr to i8 + ret i8 %a +} +; CHECK: define i8 @ptrtoint_truncates_var(i32 %ptr) { +; CHECK-NEXT: %a = trunc i32 %ptr to i8 + +define i8 @ptrtoint_truncates_global() { + %a = ptrtoint i32* @var to i8 + ret i8 %a +} +; CHECK: define i8 @ptrtoint_truncates_global() { +; CHECK-NEXT: %expanded = ptrtoint i32* @var to i32 +; CHECK-NEXT: %a = trunc i32 %expanded to i8 + define i32* @pointer_bitcast(i64* %ptr) { %cast = bitcast i64* %ptr to i32* |