aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-03-06 12:14:48 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-03-21 17:48:21 +0100
commit9f864d202558b4206adc26789aff8a204ebbe0b2 (patch)
treea1533deeca303c4aa6de55a191e53b901a6657d1
parent59dbf4d516b19dbe08d378a620b72749513611e5 (diff)
downloadllvm-9f864d202558b4206adc26789aff8a204ebbe0b2.zip
llvm-9f864d202558b4206adc26789aff8a204ebbe0b2.tar.gz
llvm-9f864d202558b4206adc26789aff8a204ebbe0b2.tar.bz2
Reapply [ConstantFold] Handle vectors in ConstantFoldLoadThroughBitcast()
There seems to be an impedance mismatch between what the type system considers an aggregate (structs and arrays) and what constants consider an aggregate (structs, arrays and vectors). Adjust the type check to consider vectors as well. The previous version of the patch dropped the type check entirely, but it turns out that getAggregateElement() does require the constant to be an aggregate in some edge cases: For Poison/Undef the getNumElements() API is called, without checking in advance that we're dealing with an aggregate. Possibly the implementation should avoid doing that, but for now I'm adding an assert so the next person doesn't fall into this trap.
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp2
-rw-r--r--llvm/lib/IR/Constants.cpp3
-rw-r--r--llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll4
-rw-r--r--llvm/test/Transforms/GVN/non-integral-pointers.ll4
4 files changed, 6 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2e2d1e3..be164a5 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -389,7 +389,7 @@ Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
// If this isn't an aggregate type, there is nothing we can do to drill down
// and find a bitcastable constant.
- if (!SrcTy->isAggregateType())
+ if (!SrcTy->isAggregateType() && !SrcTy->isVectorTy())
return nullptr;
// We're simulating a load through a pointer that was bitcast to point to
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 0f55a53..48ccb18 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -419,6 +419,9 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
}
Constant *Constant::getAggregateElement(unsigned Elt) const {
+ assert((getType()->isAggregateType() || getType()->isVectorTy()) &&
+ "Must be an aggregate/vector constant");
+
if (const auto *CC = dyn_cast<ConstantAggregate>(this))
return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
diff --git a/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll b/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
index 2aef762..d26003b 100644
--- a/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
+++ b/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
@@ -213,14 +213,12 @@ entry:
ret i64 addrspace(4)* %ref
}
-; TODO: missed optimization
define i8 addrspace(4)* @forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcopy(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
-; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
-; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
+; CHECK-NEXT: ret i8 addrspace(4)* bitcast (i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3) to i8 addrspace(4)*)
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
diff --git a/llvm/test/Transforms/GVN/non-integral-pointers.ll b/llvm/test/Transforms/GVN/non-integral-pointers.ll
index 6b9a917..07d941f 100644
--- a/llvm/test/Transforms/GVN/non-integral-pointers.ll
+++ b/llvm/test/Transforms/GVN/non-integral-pointers.ll
@@ -213,14 +213,12 @@ entry:
ret i64 addrspace(4)* %ref
}
-; TODO: missed optimization
define i8 addrspace(4)* @forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcopy(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
-; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
-; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
+; CHECK-NEXT: ret i8 addrspace(4)* bitcast (i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3) to i8 addrspace(4)*)
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*