Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4977,14 +4977,6 @@ if (ConsiderFlags && Op->hasPoisonGeneratingFlags()) return true; - // TODO: this should really be under the ConsiderFlags block, but currently - // these are not dropped by dropPoisonGeneratingFlags - if (const auto *FP = dyn_cast(Op)) { - auto FMF = FP->getFastMathFlags(); - if (FMF.noNaNs() || FMF.noInfs()) - return true; - } - unsigned Opcode = Op->getOpcode(); // Check whether opcode is a poison/undef-generating operation Index: llvm/lib/IR/Instruction.cpp =================================================================== --- llvm/lib/IR/Instruction.cpp +++ llvm/lib/IR/Instruction.cpp @@ -166,7 +166,10 @@ cast(this)->setIsInBounds(false); break; } - // TODO: FastMathFlags! + if (isa(this)) { + setHasNoNaNs(false); + setHasNoInfs(false); + } assert(!hasPoisonGeneratingFlags() && "must be kept in sync"); } Index: llvm/lib/IR/Operator.cpp =================================================================== --- llvm/lib/IR/Operator.cpp +++ llvm/lib/IR/Operator.cpp @@ -39,9 +39,10 @@ return GEP->isInBounds() || GEP->getInRangeIndex() != None; } default: + if (const auto *FP = dyn_cast(this)) + return FP->hasNoNaNs() || FP->hasNoInfs(); return false; } - // TODO: FastMathFlags! (On instructions, but not constexpr) } Type *GEPOperator::getSourceElementType() const { Index: llvm/test/Transforms/InstCombine/freeze.ll =================================================================== --- llvm/test/Transforms/InstCombine/freeze.ll +++ llvm/test/Transforms/InstCombine/freeze.ll @@ -365,9 +365,9 @@ define float @propagate_drop_fneg(float %arg) { ; CHECK-LABEL: @propagate_drop_fneg( -; CHECK-NEXT: [[V1:%.*]] = fneg nnan ninf float [[ARG:%.*]] -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fneg float [[ARG_FR]] +; CHECK-NEXT: ret float [[V1]] ; %v1 = fneg ninf nnan float %arg %v1.fr = freeze float %v1 @@ -377,9 +377,9 @@ define float @propagate_drop_fadd(float %arg) { ; CHECK-LABEL: @propagate_drop_fadd( -; CHECK-NEXT: [[V1:%.*]] = fadd nnan ninf float [[ARG:%.*]], 2.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fadd float [[ARG_FR]], 2.000000e+00 +; CHECK-NEXT: ret float [[V1]] ; %v1 = fadd ninf nnan float %arg, 2.0 %v1.fr = freeze float %v1 @@ -388,9 +388,9 @@ define float @propagate_drop_fsub(float %arg) { ; CHECK-LABEL: @propagate_drop_fsub( -; CHECK-NEXT: [[V1:%.*]] = fadd nnan ninf float [[ARG:%.*]], -2.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fadd float [[ARG_FR]], -2.000000e+00 +; CHECK-NEXT: ret float [[V1]] ; %v1 = fsub ninf nnan float %arg, 2.0 %v1.fr = freeze float %v1 @@ -399,9 +399,9 @@ define float @propagate_drop_fmul(float %arg) { ; CHECK-LABEL: @propagate_drop_fmul( -; CHECK-NEXT: [[V1:%.*]] = fmul nnan ninf float [[ARG:%.*]], 2.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fmul float [[ARG_FR]], 2.000000e+00 +; CHECK-NEXT: ret float [[V1]] ; %v1 = fmul ninf nnan float %arg, 2.0 %v1.fr = freeze float %v1 @@ -410,9 +410,9 @@ define float @propagate_drop_fdiv(float %arg) { ; CHECK-LABEL: @propagate_drop_fdiv( -; CHECK-NEXT: [[V1:%.*]] = fmul nnan ninf float [[ARG:%.*]], 5.000000e-01 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fmul float [[ARG_FR]], 5.000000e-01 +; CHECK-NEXT: ret float [[V1]] ; %v1 = fdiv ninf nnan float %arg, 2.0 %v1.fr = freeze float %v1 @@ -421,9 +421,9 @@ define float @propagate_drop_frem(float %arg) { ; CHECK-LABEL: @propagate_drop_frem( -; CHECK-NEXT: [[V1:%.*]] = frem nnan ninf float [[ARG:%.*]], 2.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = frem float [[ARG_FR]], 2.000000e+00 +; CHECK-NEXT: ret float [[V1]] ; %v1 = frem ninf nnan float %arg, 2.0 %v1.fr = freeze float %v1 @@ -432,9 +432,9 @@ define i1 @propagate_drop_fcmp(float %arg) { ; CHECK-LABEL: @propagate_drop_fcmp( -; CHECK-NEXT: [[V1:%.*]] = fcmp nnan ninf une float [[ARG:%.*]], 2.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze i1 [[V1]] -; CHECK-NEXT: ret i1 [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze float [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = fcmp une float [[ARG_FR]], 2.000000e+00 +; CHECK-NEXT: ret i1 [[V1]] ; %v1 = fcmp ninf nnan une float %arg, 2.0 %v1.fr = freeze i1 %v1 @@ -443,9 +443,9 @@ define float @propagate_drop_fmath_select(i1 %arg) { ; CHECK-LABEL: @propagate_drop_fmath_select( -; CHECK-NEXT: [[V1:%.*]] = select nnan ninf i1 [[ARG:%.*]], float 1.000000e+00, float -1.000000e+00 -; CHECK-NEXT: [[V1_FR:%.*]] = freeze float [[V1]] -; CHECK-NEXT: ret float [[V1_FR]] +; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i1 [[ARG:%.*]] +; CHECK-NEXT: [[V1:%.*]] = select i1 [[ARG_FR]], float 1.000000e+00, float -1.000000e+00 +; CHECK-NEXT: ret float [[V1]] ; %v1 = select ninf nnan i1 %arg, float 1.0, float -1.0 %v1.fr = freeze float %v1 Index: llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll =================================================================== --- llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll +++ llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll @@ -371,7 +371,7 @@ define <4 x double> @fdiv_constant_op0(<4 x double> %v) { ; CHECK-LABEL: @fdiv_constant_op0( -; CHECK-NEXT: [[B:%.*]] = fdiv fast <4 x double> , [[V:%.*]] +; CHECK-NEXT: [[B:%.*]] = fdiv reassoc nsz arcp contract afn <4 x double> , [[V:%.*]] ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[S]] ; @@ -778,7 +778,7 @@ define <4 x double> @fdiv_fdiv(<4 x double> %v0) { ; CHECK-LABEL: @fdiv_fdiv( -; CHECK-NEXT: [[T3:%.*]] = fdiv nnan arcp <4 x double> , [[V0:%.*]] +; CHECK-NEXT: [[T3:%.*]] = fdiv arcp <4 x double> , [[V0:%.*]] ; CHECK-NEXT: ret <4 x double> [[T3]] ; %t1 = fdiv fast <4 x double> , %v0 @@ -1271,7 +1271,7 @@ define <4 x double> @frem_2_vars(<4 x double> %v0, <4 x double> %v1) { ; CHECK-LABEL: @frem_2_vars( ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x double> [[V0:%.*]], <4 x double> [[V1:%.*]], <4 x i32> -; CHECK-NEXT: [[T3:%.*]] = frem nnan <4 x double> , [[TMP1]] +; CHECK-NEXT: [[T3:%.*]] = frem <4 x double> , [[TMP1]] ; CHECK-NEXT: ret <4 x double> [[T3]] ; %t1 = frem nnan ninf <4 x double> , %v0 Index: llvm/test/Transforms/InstCombine/shuffle_select.ll =================================================================== --- llvm/test/Transforms/InstCombine/shuffle_select.ll +++ llvm/test/Transforms/InstCombine/shuffle_select.ll @@ -371,7 +371,7 @@ define <4 x double> @fdiv_constant_op0(<4 x double> %v) { ; CHECK-LABEL: @fdiv_constant_op0( -; CHECK-NEXT: [[B:%.*]] = fdiv fast <4 x double> , [[V:%.*]] +; CHECK-NEXT: [[B:%.*]] = fdiv reassoc nsz arcp contract afn <4 x double> , [[V:%.*]] ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[S]] ; @@ -778,7 +778,7 @@ define <4 x double> @fdiv_fdiv(<4 x double> %v0) { ; CHECK-LABEL: @fdiv_fdiv( -; CHECK-NEXT: [[T3:%.*]] = fdiv nnan arcp <4 x double> , [[V0:%.*]] +; CHECK-NEXT: [[T3:%.*]] = fdiv arcp <4 x double> , [[V0:%.*]] ; CHECK-NEXT: ret <4 x double> [[T3]] ; %t1 = fdiv fast <4 x double> , %v0 @@ -1271,7 +1271,7 @@ define <4 x double> @frem_2_vars(<4 x double> %v0, <4 x double> %v1) { ; CHECK-LABEL: @frem_2_vars( ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x double> [[V0:%.*]], <4 x double> [[V1:%.*]], <4 x i32> -; CHECK-NEXT: [[T3:%.*]] = frem nnan <4 x double> , [[TMP1]] +; CHECK-NEXT: [[T3:%.*]] = frem <4 x double> , [[TMP1]] ; CHECK-NEXT: ret <4 x double> [[T3]] ; %t1 = frem nnan ninf <4 x double> , %v0 Index: llvm/test/Transforms/InstCombine/vec_demanded_elts-inseltpoison.ll =================================================================== --- llvm/test/Transforms/InstCombine/vec_demanded_elts-inseltpoison.ll +++ llvm/test/Transforms/InstCombine/vec_demanded_elts-inseltpoison.ll @@ -435,7 +435,7 @@ define <3 x float> @shuf_fsub(<3 x float> %x) { ; CHECK-LABEL: @shuf_fsub( -; CHECK-NEXT: [[BO:%.*]] = fsub fast <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = fsub reassoc nsz arcp contract afn <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> poison, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -457,7 +457,7 @@ define <3 x float> @shuf_fdiv_const_op0(<3 x float> %x) { ; CHECK-LABEL: @shuf_fdiv_const_op0( -; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc ninf <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> poison, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -468,7 +468,7 @@ define <3 x float> @shuf_fdiv_const_op1(<3 x float> %x) { ; CHECK-LABEL: @shuf_fdiv_const_op1( -; CHECK-NEXT: [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], +; CHECK-NEXT: [[BO:%.*]] = fdiv <3 x float> [[X:%.*]], ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> poison, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -479,7 +479,7 @@ define <3 x float> @shuf_frem_const_op0(<3 x float> %x) { ; CHECK-LABEL: @shuf_frem_const_op0( -; CHECK-NEXT: [[BO:%.*]] = frem nnan <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = frem <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> poison, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -490,7 +490,7 @@ define <3 x float> @shuf_frem_const_op1(<3 x float> %x) { ; CHECK-LABEL: @shuf_frem_const_op1( -; CHECK-NEXT: [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], +; CHECK-NEXT: [[BO:%.*]] = frem reassoc <3 x float> [[X:%.*]], ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> poison, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; Index: llvm/test/Transforms/InstCombine/vec_demanded_elts.ll =================================================================== --- llvm/test/Transforms/InstCombine/vec_demanded_elts.ll +++ llvm/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -435,7 +435,7 @@ define <3 x float> @shuf_fsub(<3 x float> %x) { ; CHECK-LABEL: @shuf_fsub( -; CHECK-NEXT: [[BO:%.*]] = fsub fast <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = fsub reassoc nsz arcp contract afn <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -457,7 +457,7 @@ define <3 x float> @shuf_fdiv_const_op0(<3 x float> %x) { ; CHECK-LABEL: @shuf_fdiv_const_op0( -; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc ninf <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -468,7 +468,7 @@ define <3 x float> @shuf_fdiv_const_op1(<3 x float> %x) { ; CHECK-LABEL: @shuf_fdiv_const_op1( -; CHECK-NEXT: [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], +; CHECK-NEXT: [[BO:%.*]] = fdiv <3 x float> [[X:%.*]], ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -479,7 +479,7 @@ define <3 x float> @shuf_frem_const_op0(<3 x float> %x) { ; CHECK-LABEL: @shuf_frem_const_op0( -; CHECK-NEXT: [[BO:%.*]] = frem nnan <3 x float> , [[X:%.*]] +; CHECK-NEXT: [[BO:%.*]] = frem <3 x float> , [[X:%.*]] ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; @@ -490,7 +490,7 @@ define <3 x float> @shuf_frem_const_op1(<3 x float> %x) { ; CHECK-LABEL: @shuf_frem_const_op1( -; CHECK-NEXT: [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], +; CHECK-NEXT: [[BO:%.*]] = frem reassoc <3 x float> [[X:%.*]], ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> ; CHECK-NEXT: ret <3 x float> [[R]] ; Index: llvm/test/Transforms/PhaseOrdering/ARM/mve-floatreduce.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/ARM/mve-floatreduce.ll +++ llvm/test/Transforms/PhaseOrdering/ARM/mve-floatreduce.ll @@ -13,7 +13,7 @@ ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x half> [[TMP1]] to <4 x i32> ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <4 x i32> ; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP3]] to <8 x half> -; CHECK-NEXT: [[TMP5:%.*]] = fadd fast <8 x half> [[TMP1]], [[TMP4]] +; CHECK-NEXT: [[TMP5:%.*]] = fadd reassoc nsz arcp contract afn <8 x half> [[TMP1]], [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <8 x half> [[TMP5]], i32 0 ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <8 x half> [[TMP5]], i32 4 ; CHECK-NEXT: [[ADD:%.*]] = fadd fast half [[TMP6]], [[TMP7]]