[ValueTracking] improve undef/poison analysis for constant vectors

Differential Revision: https://reviews.llvm.org/D76702
This commit is contained in:
Sanjay Patel 2020-03-24 13:34:39 -04:00
parent b8dab9b3d5
commit 88b493a838
2 changed files with 35 additions and 9 deletions

View File

@ -4610,9 +4610,22 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,
// TODO: Some instructions are guaranteed to return neither undef
// nor poison if their arguments are not poison/undef.
// TODO: Deal with other Constant subclasses.
if (isa<ConstantInt>(V) || isa<GlobalVariable>(V))
return true;
if (auto *C = dyn_cast<Constant>(V)) {
// TODO: We can analyze ConstExpr by opcode to determine if there is any
// possibility of poison.
if (isa<UndefValue>(C) || isa<ConstantExpr>(C))
return false;
// TODO: Add ConstantFP and pointers.
if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) )
return true;
if (C->getType()->isVectorTy())
return !C->containsUndefElement() && !C->containsConstantExpression();
// TODO: Recursively analyze aggregates or other constants.
return false;
}
if (auto PN = dyn_cast<PHINode>(V)) {
if (llvm::all_of(PN->incoming_values(), [](const Use &U) {

View File

@ -19,6 +19,8 @@ define i32 @make_const() {
ret i32 %x
}
; TODO: This is not poison.
define float @make_const2() {
; CHECK-LABEL: @make_const2(
; CHECK-NEXT: [[X:%.*]] = freeze float 1.000000e+01
@ -38,6 +40,8 @@ define i32* @make_const_glb() {
ret i32* %k
}
; TODO: This is not poison.
define i32()* @make_const_fn() {
; CHECK-LABEL: @make_const_fn(
; CHECK-NEXT: [[K:%.*]] = freeze i32 ()* @make_const
@ -47,6 +51,8 @@ define i32()* @make_const_fn() {
ret i32()* %k
}
; TODO: This is not poison.
define i32* @make_const_null() {
; CHECK-LABEL: @make_const_null(
; CHECK-NEXT: [[K:%.*]] = freeze i32* null
@ -58,8 +64,7 @@ define i32* @make_const_null() {
define <2 x i32> @constvector() {
; CHECK-LABEL: @constvector(
; CHECK-NEXT: [[X:%.*]] = freeze <2 x i32> <i32 0, i32 1>
; CHECK-NEXT: ret <2 x i32> [[X]]
; CHECK-NEXT: ret <2 x i32> <i32 0, i32 1>
;
%x = freeze <2 x i32> <i32 0, i32 1>
ret <2 x i32> %x
@ -67,8 +72,7 @@ define <2 x i32> @constvector() {
define <3 x i5> @constvector_weird() {
; CHECK-LABEL: @constvector_weird(
; CHECK-NEXT: [[X:%.*]] = freeze <3 x i5> <i5 0, i5 1, i5 10>
; CHECK-NEXT: ret <3 x i5> [[X]]
; CHECK-NEXT: ret <3 x i5> <i5 0, i5 1, i5 10>
;
%x = freeze <3 x i5> <i5 0, i5 1, i5 42>
ret <3 x i5> %x
@ -76,13 +80,14 @@ define <3 x i5> @constvector_weird() {
define <2 x float> @constvector_FP() {
; CHECK-LABEL: @constvector_FP(
; CHECK-NEXT: [[X:%.*]] = freeze <2 x float> <float 0.000000e+00, float 1.000000e+00>
; CHECK-NEXT: ret <2 x float> [[X]]
; CHECK-NEXT: ret <2 x float> <float 0.000000e+00, float 1.000000e+00>
;
%x = freeze <2 x float> <float 0.0, float 1.0>
ret <2 x float> %x
}
; Negative test
define <2 x i32> @constvector_noopt() {
; CHECK-LABEL: @constvector_noopt(
; CHECK-NEXT: [[X:%.*]] = freeze <2 x i32> <i32 0, i32 undef>
@ -92,6 +97,8 @@ define <2 x i32> @constvector_noopt() {
ret <2 x i32> %x
}
; Negative test
define <3 x i5> @constvector_weird_noopt() {
; CHECK-LABEL: @constvector_weird_noopt(
; CHECK-NEXT: [[X:%.*]] = freeze <3 x i5> <i5 0, i5 undef, i5 10>
@ -101,6 +108,8 @@ define <3 x i5> @constvector_weird_noopt() {
ret <3 x i5> %x
}
; Negative test
define <2 x float> @constvector_FP_noopt() {
; CHECK-LABEL: @constvector_FP_noopt(
; CHECK-NEXT: [[X:%.*]] = freeze <2 x float> <float 0.000000e+00, float undef>
@ -112,6 +121,8 @@ define <2 x float> @constvector_FP_noopt() {
@g = external global i16, align 1
; Negative test
define float @constant_expr() {
; CHECK-LABEL: @constant_expr(
; CHECK-NEXT: [[R:%.*]] = freeze float bitcast (i32 ptrtoint (i16* @g to i32) to float)
@ -121,6 +132,8 @@ define float @constant_expr() {
ret float %r
}
; Negative test
define <2 x i31> @vector_element_constant_expr() {
; CHECK-LABEL: @vector_element_constant_expr(
; CHECK-NEXT: [[R:%.*]] = freeze <2 x i31> <i31 34, i31 ptrtoint (i16* @g to i31)>