aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/NaCl/ReplacePtrsWithInts.cpp20
-rw-r--r--test/Transforms/NaCl/replace-ptrs-with-ints.ll15
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*