Teach InlineCost about address spaces
Summary:
I basically copied this patch from here:
https://reviews.llvm.org/D1251
But I skipped some of the refactoring to make the patch more clean.
The new outer3/inner3 test case in ptr-diff.ll triggers the
following assert without this patch:
lib/IR/Constants.cpp:1834: static llvm::Constant *llvm::ConstantExpr::getCompare(unsigned short, llvm::Constant *, llvm::Constant *, bool): Assertion `C1->getType() == C2->getType() && "Op types should be identical!"' failed.
The other new test cases makes sure that there is code coverage
for all modifications in InlineCost.cpp (getting different values
due to not fetching sizes for address space zero). I only guarantee
code coverage for those tests. The tests are not written in a way
that they would break if not having the corrections in
InlineCost.cpp. I found it quite hard to fine tune the tests into
getting different results based on the pointer sizes (except for
the test case where we hit an assert if not teaching InlineCost
about address spaces).
Reviewers: chandlerc, arsenm, haicheng
Reviewed By: arsenm
Subscribers: wdng, eraman, llvm-commits, haicheng
Differential Revision: https://reviews.llvm.org/D40455
llvm-svn: 321809
diff --git a/llvm/test/Transforms/Inline/byval.ll b/llvm/test/Transforms/Inline/byval.ll
index aeb9964..3e57bfa 100644
--- a/llvm/test/Transforms/Inline/byval.ll
+++ b/llvm/test/Transforms/Inline/byval.ll
@@ -1,6 +1,8 @@
; RUN: opt < %s -inline -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
+target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64"
+
; Inlining a byval struct should cause an explicit copy into an alloca.
%struct.ss = type { i32, i64 }
@@ -128,3 +130,27 @@
; CHECK: store i32 0, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
; CHECK-NOT: load i32, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
}
+
+%struct.S1 = type { i32 }
+
+@d = addrspace(1) global %struct.S1 { i32 1 }, align 4
+@c = common addrspace(1) global i32 0, align 4
+
+define internal void @f5_as1(%struct.S1 addrspace(1)* byval nocapture readonly align 4 %p) {
+entry:
+ store i32 0, i32 addrspace(1)* getelementptr inbounds (%struct.S1, %struct.S1 addrspace(1)* @d, i64 0, i32 0), align 4
+ %f2 = getelementptr inbounds %struct.S1, %struct.S1 addrspace(1)* %p, i64 0, i32 0
+ %0 = load i32, i32 addrspace(1)* %f2, align 4
+ store i32 %0, i32 addrspace(1)* @c, align 4
+ ret void
+}
+
+define i32 @test5_as1() {
+entry:
+ tail call void @f5_as1(%struct.S1 addrspace(1)* byval align 4 @d)
+ %0 = load i32, i32 addrspace(1)* @c, align 4
+ ret i32 %0
+; CHECK: @test5_as1()
+; CHECK: store i32 0, i32 addrspace(1)* getelementptr inbounds (%struct.S1, %struct.S1 addrspace(1)* @d, i64 0, i32 0), align 4
+; CHECK-NOT: load i32, i32 addrspace(1)* getelementptr inbounds (%struct.S1, %struct.S1 addrspace(1)* @d, i64 0, i32 0), align 4
+}