summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/TargetTransformInfo.cpp22
-rw-r--r--test/Transforms/Inline/ptr-diff.ll45
2 files changed, 59 insertions, 8 deletions
diff --git a/lib/Analysis/TargetTransformInfo.cpp b/lib/Analysis/TargetTransformInfo.cpp
index 0a215aa53c..8c6005b31c 100644
--- a/lib/Analysis/TargetTransformInfo.cpp
+++ b/lib/Analysis/TargetTransformInfo.cpp
@@ -269,26 +269,34 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
// Otherwise, the default basic cost is used.
return TCC_Basic;
- case Instruction::IntToPtr:
+ case Instruction::IntToPtr: {
+ if (!DL)
+ return TCC_Basic;
+
// An inttoptr cast is free so long as the input is a legal integer type
// which doesn't contain values outside the range of a pointer.
- if (DL && DL->isLegalInteger(OpTy->getScalarSizeInBits()) &&
- OpTy->getScalarSizeInBits() <= DL->getPointerSizeInBits())
+ unsigned OpSize = OpTy->getScalarSizeInBits();
+ if (DL->isLegalInteger(OpSize) &&
+ OpSize <= DL->getPointerTypeSizeInBits(Ty))
return TCC_Free;
// Otherwise it's not a no-op.
return TCC_Basic;
+ }
+ case Instruction::PtrToInt: {
+ if (!DL)
+ return TCC_Basic;
- case Instruction::PtrToInt:
// A ptrtoint cast is free so long as the result is large enough to store
// the pointer, and a legal integer type.
- if (DL && DL->isLegalInteger(Ty->getScalarSizeInBits()) &&
- Ty->getScalarSizeInBits() >= DL->getPointerSizeInBits())
+ unsigned DestSize = Ty->getScalarSizeInBits();
+ if (DL->isLegalInteger(DestSize) &&
+ DestSize >= DL->getPointerTypeSizeInBits(OpTy))
return TCC_Free;
// Otherwise it's not a no-op.
return TCC_Basic;
-
+ }
case Instruction::Trunc:
// trunc to a native type is free (assuming the target has compare and
// shift-right of the same width).
diff --git a/test/Transforms/Inline/ptr-diff.ll b/test/Transforms/Inline/ptr-diff.ll
index 01b42daddf..af42bc7ced 100644
--- a/test/Transforms/Inline/ptr-diff.ll
+++ b/test/Transforms/Inline/ptr-diff.ll
@@ -1,6 +1,6 @@
; RUN: opt -inline < %s -S -o - -inline-threshold=10 | FileCheck %s
-target datalayout = "p:32:32"
+target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64"
define i32 @outer1() {
; CHECK-LABEL: @outer1(
@@ -56,3 +56,46 @@ else:
%t = load i32* %begin
ret i32 %t
}
+
+; The inttoptrs are free since it is a smaller integer to a larger
+; pointer size
+define i32 @inttoptr_free_cost(i32 %a, i32 %b, i32 %c) {
+ %p1 = inttoptr i32 %a to i32 addrspace(1)*
+ %p2 = inttoptr i32 %b to i32 addrspace(1)*
+ %p3 = inttoptr i32 %c to i32 addrspace(1)*
+ %t1 = load i32 addrspace(1)* %p1
+ %t2 = load i32 addrspace(1)* %p2
+ %t3 = load i32 addrspace(1)* %p3
+ %s = add i32 %t1, %t2
+ %s1 = add i32 %s, %t3
+ ret i32 %s1
+}
+
+define i32 @inttoptr_free_cost_user(i32 %begin, i32 %end) {
+; CHECK-LABEL: @inttoptr_free_cost_user(
+; CHECK-NOT: call
+ %x = call i32 @inttoptr_free_cost(i32 %begin, i32 %end, i32 9)
+ ret i32 %x
+}
+
+; The inttoptrs have a cost since it is a larger integer to a smaller
+; pointer size
+define i32 @inttoptr_cost_smaller_ptr(i32 %a, i32 %b, i32 %c) {
+ %p1 = inttoptr i32 %a to i32 addrspace(2)*
+ %p2 = inttoptr i32 %b to i32 addrspace(2)*
+ %p3 = inttoptr i32 %c to i32 addrspace(2)*
+ %t1 = load i32 addrspace(2)* %p1
+ %t2 = load i32 addrspace(2)* %p2
+ %t3 = load i32 addrspace(2)* %p3
+ %s = add i32 %t1, %t2
+ %s1 = add i32 %s, %t3
+ ret i32 %s1
+}
+
+define i32 @inttoptr_cost_smaller_ptr_user(i32 %begin, i32 %end) {
+; CHECK-LABEL: @inttoptr_cost_smaller_ptr_user(
+; CHECK: call
+ %x = call i32 @inttoptr_cost_smaller_ptr(i32 %begin, i32 %end, i32 9)
+ ret i32 %x
+}
+