Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4610,10 +4610,16 @@ // 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)) + if (isa(V)) return true; + // Constants (except possibly for constant expressions) are never poison, + // so check for ConstantExpr or undef. + if (auto *C = dyn_cast(V)) { + return !isa(C) && !isa(C) && + !C->containsUndefElement() && !C->containsConstantExpression(); + } + if (auto PN = dyn_cast(V)) { if (llvm::all_of(PN->incoming_values(), [](const Use &U) { return isa(U.get()); Index: llvm/test/Transforms/InstSimplify/freeze.ll =================================================================== --- llvm/test/Transforms/InstSimplify/freeze.ll +++ llvm/test/Transforms/InstSimplify/freeze.ll @@ -21,8 +21,7 @@ define float @make_const2() { ; CHECK-LABEL: @make_const2( -; CHECK-NEXT: [[X:%.*]] = freeze float 1.000000e+01 -; CHECK-NEXT: ret float [[X]] +; CHECK-NEXT: ret float 1.000000e+01 ; %x = freeze float 10.0 ret float %x @@ -40,8 +39,7 @@ define i32()* @make_const_fn() { ; CHECK-LABEL: @make_const_fn( -; CHECK-NEXT: [[K:%.*]] = freeze i32 ()* @make_const -; CHECK-NEXT: ret i32 ()* [[K]] +; CHECK-NEXT: ret i32 ()* @make_const ; %k = freeze i32()* @make_const ret i32()* %k @@ -49,8 +47,7 @@ define i32* @make_const_null() { ; CHECK-LABEL: @make_const_null( -; CHECK-NEXT: [[K:%.*]] = freeze i32* null -; CHECK-NEXT: ret i32* [[K]] +; CHECK-NEXT: ret i32* null ; %k = freeze i32* null ret i32* %k @@ -58,8 +55,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 +63,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 +71,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 +88,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 +99,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 +112,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 +123,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> @@ -195,8 +199,7 @@ define i32* @gep_inbounds_null() { ; CHECK-LABEL: @gep_inbounds_null( -; CHECK-NEXT: [[K:%.*]] = freeze i32* null -; CHECK-NEXT: ret i32* [[K]] +; CHECK-NEXT: ret i32* null ; %p = getelementptr inbounds i32, i32* null, i32 0 %k = freeze i32* %p