From fd8928ded9fa74d7127d4277440d5928145ebc7e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 27 Jul 2015 18:31:03 +0000 Subject: [PATCH] Fix assert when inlining a constantexpr addrspacecast The pointer size of the addrspacecasted pointer might not have matched, so this would have hit an assert in accumulateConstantOffset. I think this was here to allow constant folding of a load of an addrspacecasted constant. Accumulating the offset through the addrspacecast doesn't make much sense, so something else is necessary to allow folding the load through this cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243300 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ConstantFolding.cpp | 3 +- test/Transforms/ConstProp/loads.ll | 7 +++-- ...inline-constexpr-addrspacecast-argument.ll | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 test/Transforms/Inline/inline-constexpr-addrspacecast-argument.ll diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 70c929b53a3..07f53bedc77 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -248,8 +248,7 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, // Look through ptr->int and ptr->ptr casts. if (CE->getOpcode() == Instruction::PtrToInt || - CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::AddrSpaceCast) + CE->getOpcode() == Instruction::BitCast) return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL); // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5) diff --git a/test/Transforms/ConstProp/loads.ll b/test/Transforms/ConstProp/loads.ll index 5426ad0f8ad..89387ad06ba 100644 --- a/test/Transforms/ConstProp/loads.ll +++ b/test/Transforms/ConstProp/loads.ll @@ -40,13 +40,16 @@ define i16 @test2_addrspacecast() { %r = load i16, i16 addrspace(1)* addrspacecast(i32* getelementptr ({{i32,i8},i32}, {{i32,i8},i32}* @g1, i32 0, i32 0, i32 0) to i16 addrspace(1)*) ret i16 %r +; FIXME: Should be able to load through a constant addrspacecast. ; 0xBEEF ; LE-LABEL: @test2_addrspacecast( -; LE: ret i16 -16657 +; XLE: ret i16 -16657 +; LE: load i16, i16 addrspace(1)* addrspacecast ; 0xDEAD ; BE-LABEL: @test2_addrspacecast( -; BE: ret i16 -8531 +; XBE: ret i16 -8531 +; BE: load i16, i16 addrspace(1)* addrspacecast } ; Load of second 16 bits of 32-bit value. diff --git a/test/Transforms/Inline/inline-constexpr-addrspacecast-argument.ll b/test/Transforms/Inline/inline-constexpr-addrspacecast-argument.ll new file mode 100644 index 00000000000..498a995ecd4 --- /dev/null +++ b/test/Transforms/Inline/inline-constexpr-addrspacecast-argument.ll @@ -0,0 +1,30 @@ +; RUN: opt -S -inline < %s | FileCheck %s + +target datalayout = "e-p3:32:32-p4:64:64-n32" + +@lds = internal addrspace(3) global [64 x i64] zeroinitializer + +; CHECK-LABEL: @constexpr_addrspacecast_ptr_size_change( +; CHECK: load i64, i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* addrspacecast (i64 addrspace(3)* getelementptr inbounds ([64 x i64], [64 x i64] addrspace(3)* @lds, i32 0, i32 0) to i64 addrspace(4)*), i64 undef) +; CHECK-NEXT: br +define void @constexpr_addrspacecast_ptr_size_change() #0 { + %tmp0 = call i32 @foo(i64 addrspace(4)* addrspacecast (i64 addrspace(3)* getelementptr inbounds ([64 x i64], [64 x i64] addrspace(3)* @lds, i32 0, i32 0) to i64 addrspace(4)*)) #1 + ret void +} + +define i32 @foo(i64 addrspace(4)* %arg) #1 { +bb: + %tmp = getelementptr i64, i64 addrspace(4)* %arg, i64 undef + %tmp1 = load i64, i64 addrspace(4)* %tmp + br i1 undef, label %bb2, label %bb3 + +bb2: + store i64 0, i64 addrspace(4)* %tmp + br label %bb3 + +bb3: + unreachable +} + +attributes #0 = { nounwind } +attributes #1 = { alwaysinline nounwind } -- 2.34.1