Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -248,8 +248,7 @@ // 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) Index: test/Transforms/ConstProp/loads.ll =================================================================== --- test/Transforms/ConstProp/loads.ll +++ test/Transforms/ConstProp/loads.ll @@ -40,13 +40,16 @@ %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. Index: test/Transforms/Inline/inline-constexpr-addrspacecast-argument.ll =================================================================== --- /dev/null +++ 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 }