From: Yaxun Liu Date: Mon, 21 Nov 2016 15:42:31 +0000 (+0000) Subject: Fix known zero bits for addrspacecast. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f570b5fd165fcdc765e32f3a7ddc830270069e8c;p=llvm Fix known zero bits for addrspacecast. Currently LLVM assumes that a pointer addrspacecasted to a different addr space is equivalent to trunc or zext bitwise, which is not true. For example, in amdgcn target, when a null pointer is addrspacecasted from addr space 4 to 0, its value is changed from i64 0 to i32 -1. This patch teaches LLVM not to assume known bits of addrspacecast instruction to its operand. Differential Revision: https://reviews.llvm.org/D26803 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287545 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 18117f66a34..234d42dfa91 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -1025,7 +1025,6 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero, break; // Can't work with floating point. case Instruction::PtrToInt: case Instruction::IntToPtr: - case Instruction::AddrSpaceCast: // Pointers could be different sizes. // Fall through and handle them the same as zext/trunc. LLVM_FALLTHROUGH; case Instruction::ZExt: diff --git a/test/Analysis/ValueTracking/knownzero-addrspacecast.ll b/test/Analysis/ValueTracking/knownzero-addrspacecast.ll new file mode 100644 index 00000000000..94ba209e207 --- /dev/null +++ b/test/Analysis/ValueTracking/knownzero-addrspacecast.ll @@ -0,0 +1,24 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +; When a pointer is addrspacecasted to a another addr space, we cannot assume +; anything about the new bits. + +target datalayout = "p:32:32-p3:32:32-p4:64:64" + +; CHECK-LABEL: @test_shift +; CHECK-NOT: ret i64 0 +define i64 @test_shift(i8* %p) { + %g = addrspacecast i8* %p to i8 addrspace(4)* + %i = ptrtoint i8 addrspace(4)* %g to i64 + %shift = lshr i64 %i, 32 + ret i64 %shift +} + +; CHECK-LABEL: @test_null +; A null pointer casted to another addr space may no longer have null value. +; CHECK-NOT: ret i32 0 +define i32 @test_null() { + %g = addrspacecast i8* null to i8 addrspace(3)* + %i = ptrtoint i8 addrspace(3)* %g to i32 + ret i32 %i +} diff --git a/test/Transforms/InstCombine/loadstore-alignment.ll b/test/Transforms/InstCombine/loadstore-alignment.ll index 4afa82dcb4c..e821fb27181 100644 --- a/test/Transforms/InstCombine/loadstore-alignment.ll +++ b/test/Transforms/InstCombine/loadstore-alignment.ll @@ -14,33 +14,6 @@ define <2 x i64> @static_hem() { ret <2 x i64> %tmp1 } -; CHECK-LABEL: @static_hem_addrspacecast( -; CHECK: , align 16 -define <2 x i64> @static_hem_addrspacecast() { - %t = getelementptr <2 x i64>, <2 x i64>* @x, i32 7 - %t.asc = addrspacecast <2 x i64>* %t to <2 x i64> addrspace(1)* - %tmp1 = load <2 x i64>, <2 x i64> addrspace(1)* %t.asc, align 1 - ret <2 x i64> %tmp1 -} - -; CHECK-LABEL: @static_hem_addrspacecast_smaller_ptr( -; CHECK: , align 16 -define <2 x i64> @static_hem_addrspacecast_smaller_ptr() { - %t = getelementptr <2 x i64>, <2 x i64>* @x, i32 7 - %t.asc = addrspacecast <2 x i64>* %t to <2 x i64> addrspace(2)* - %tmp1 = load <2 x i64>, <2 x i64> addrspace(2)* %t.asc, align 1 - ret <2 x i64> %tmp1 -} - -; CHECK-LABEL: @static_hem_addrspacecast_larger_ptr( -; CHECK: , align 16 -define <2 x i64> @static_hem_addrspacecast_larger_ptr() { - %t = getelementptr <2 x i64>, <2 x i64> addrspace(2)* @x.as2, i32 7 - %t.asc = addrspacecast <2 x i64> addrspace(2)* %t to <2 x i64> addrspace(1)* - %tmp1 = load <2 x i64>, <2 x i64> addrspace(1)* %t.asc, align 1 - ret <2 x i64> %tmp1 -} - ; CHECK-LABEL: @hem( ; CHECK: , align 16 define <2 x i64> @hem(i32 %i) {