diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4610,9 +4610,22 @@ // 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(V) || isa(V)) - return true; + if (auto *C = dyn_cast(V)) { + // TODO: We can analyze ConstExpr by opcode to determine if there is any + // possibility of poison. + if (isa(C) || isa(C)) + return false; + + // TODO: Add ConstantFP and pointers. + if (isa(C) || isa(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(V)) { if (llvm::all_of(PN->incoming_values(), [](const Use &U) { diff --git a/llvm/test/Transforms/InstSimplify/freeze.ll b/llvm/test/Transforms/InstSimplify/freeze.ll --- a/llvm/test/Transforms/InstSimplify/freeze.ll +++ b/llvm/test/Transforms/InstSimplify/freeze.ll @@ -19,6 +19,8 @@ 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 @@ 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 @@ 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 <2 x i32> @constvector() { ; CHECK-LABEL: @constvector( -; CHECK-NEXT: [[X:%.*]] = freeze <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[X]] +; CHECK-NEXT: ret <2 x i32> ; %x = freeze <2 x i32> ret <2 x i32> %x @@ -67,8 +72,7 @@ define <3 x i5> @constvector_weird() { ; CHECK-LABEL: @constvector_weird( -; CHECK-NEXT: [[X:%.*]] = freeze <3 x i5> -; CHECK-NEXT: ret <3 x i5> [[X]] +; CHECK-NEXT: ret <3 x i5> ; %x = freeze <3 x i5> ret <3 x i5> %x @@ -76,13 +80,14 @@ define <2 x float> @constvector_FP() { ; CHECK-LABEL: @constvector_FP( -; CHECK-NEXT: [[X:%.*]] = freeze <2 x float> -; CHECK-NEXT: ret <2 x float> [[X]] +; CHECK-NEXT: ret <2 x float> ; %x = freeze <2 x float> ret <2 x float> %x } +; Negative test + define <2 x i32> @constvector_noopt() { ; CHECK-LABEL: @constvector_noopt( ; CHECK-NEXT: [[X:%.*]] = freeze <2 x i32> @@ -92,6 +97,8 @@ 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> @@ -101,6 +108,8 @@ 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> @@ -112,6 +121,8 @@ @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 @@ 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>