From: Philip Reames Date: Tue, 19 Feb 2019 23:19:51 +0000 (+0000) Subject: [GVN] Fix a non-integral pointer bug w/vector types X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7dee0ff0e5e27ec114f84937785896dce5d0e022;p=llvm [GVN] Fix a non-integral pointer bug w/vector types GVN generally doesn't forward structs or array types, but it *will* forward vector types to non-vectors and vice versa. As demonstrated in tests, we need to inhibit the same set of transforms for vector of non-integral pointers as for non-integral pointers themselves. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354401 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Utils/VNCoercion.cpp b/lib/Transforms/Utils/VNCoercion.cpp index 74572eb2d46..8e21472f2c1 100644 --- a/lib/Transforms/Utils/VNCoercion.cpp +++ b/lib/Transforms/Utils/VNCoercion.cpp @@ -31,8 +31,8 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, return false; // Don't coerce non-integral pointers to integers or vice versa. - if (DL.isNonIntegralPointerType(StoredVal->getType()) != - DL.isNonIntegralPointerType(LoadTy)) { + if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()) != + DL.isNonIntegralPointerType(LoadTy->getScalarType())) { // As a special case, allow coercion of memset used to initialize // an array w/null. Despite non-integral pointers not generally having a // specific bit pattern, we do assume null is zero. diff --git a/test/Transforms/GVN/non-integral-pointers.ll b/test/Transforms/GVN/non-integral-pointers.ll index c222a8954bd..c5a281e1423 100644 --- a/test/Transforms/GVN/non-integral-pointers.ll +++ b/test/Transforms/GVN/non-integral-pointers.ll @@ -77,6 +77,22 @@ define i8 addrspace(4)* @neg_forward_memset(i8 addrspace(4)* addrspace(4)* %loc) ret i8 addrspace(4)* %ref } +define <1 x i8 addrspace(4)*> @neg_forward_memset_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) { +; CHECK-LABEL: @neg_forward_memset_vload( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)* +; CHECK-NEXT: call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false) +; CHECK-NEXT: [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]] +; CHECK-NEXT: ret <1 x i8 addrspace(4)*> [[REF]] +; + entry: + %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)* + call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false) + %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc + ret <1 x i8 addrspace(4)*> %ref +} + + ; Can forward since we can do so w/o breaking types define i8 addrspace(4)* @forward_memset_zero(i8 addrspace(4)* addrspace(4)* %loc) { ; CHECK-LABEL: @forward_memset_zero( @@ -108,6 +124,21 @@ define i8 addrspace(4)* @neg_forward_store(i8 addrspace(4)* addrspace(4)* %loc) ret i8 addrspace(4)* %ref } +define <1 x i8 addrspace(4)*> @neg_forward_store_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) { +; CHECK-LABEL: @neg_forward_store_vload( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)* +; CHECK-NEXT: store i64 5, i64 addrspace(4)* [[LOC_BC]] +; CHECK-NEXT: [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]] +; CHECK-NEXT: ret <1 x i8 addrspace(4)*> [[REF]] +; + entry: + %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i64 addrspace(4)* + store i64 5, i64 addrspace(4)* %loc.bc + %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc + ret <1 x i8 addrspace(4)*> %ref +} + ; TODO: missed optimization, we can forward the null. define i8 addrspace(4)* @forward_store_zero(i8 addrspace(4)* addrspace(4)* %loc) { ; CHECK-LABEL: @forward_store_zero(