Skip to content

release/20.x: [InstCombine] Fix FMF propagation in foldSelectWithFCmpToFabs (#121580) #125338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2852,10 +2852,10 @@ static Instruction *foldSelectWithFCmpToFabs(SelectInst &SI,
if (!match(TrueVal, m_FNeg(m_Specific(X))))
return nullptr;

// Forward-propagate nnan and ninf from the fneg to the select.
// Forward-propagate nnan and ninf from the fcmp to the select.
// If all inputs are not those values, then the select is not either.
// Note: nsz is defined differently, so it may not be correct to propagate.
FastMathFlags FMF = cast<FPMathOperator>(TrueVal)->getFastMathFlags();
FastMathFlags FMF = cast<FPMathOperator>(CondVal)->getFastMathFlags();
if (FMF.noNaNs() && !SI.hasNoNaNs()) {
SI.setHasNoNaNs(true);
ChangedFMF = true;
Expand All @@ -2864,6 +2864,13 @@ static Instruction *foldSelectWithFCmpToFabs(SelectInst &SI,
SI.setHasNoInfs(true);
ChangedFMF = true;
}
// Forward-propagate nnan from the fneg to the select.
// The nnan flag can be propagated iff fneg is selected when X is NaN.
if (!SI.hasNoNaNs() && cast<FPMathOperator>(TrueVal)->hasNoNaNs() &&
(Swap ? FCmpInst::isOrdered(Pred) : FCmpInst::isUnordered(Pred))) {
SI.setHasNoNaNs(true);
ChangedFMF = true;
}

// With nsz, when 'Swap' is false:
// fold (X < +/-0.0) ? -X : X or (X <= +/-0.0) ? -X : X to fabs(X)
Expand Down
40 changes: 20 additions & 20 deletions llvm/test/Transforms/InstCombine/fabs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ define double @select_fcmp_nnan_nsz_olt_zero(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%ltzero = fcmp olt double %x, 0.0
Expand Down Expand Up @@ -523,7 +523,7 @@ define double @select_fcmp_nnan_nsz_olt_zero_unary_fneg(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero_unary_fneg(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%ltzero = fcmp olt double %x, 0.0
Expand Down Expand Up @@ -553,7 +553,7 @@ define float @select_fcmp_nnan_nsz_olt_negzero(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%ltzero = fcmp olt float %x, -0.0
Expand All @@ -579,7 +579,7 @@ define float @select_fcmp_nnan_nsz_ult_negzero(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%ltzero = fcmp ult float %x, -0.0
Expand All @@ -592,7 +592,7 @@ define float @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%ltzero = fcmp olt float %x, -0.0
Expand All @@ -607,7 +607,7 @@ define float @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(
; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%ltzero = fcmp ult float %x, -0.0
Expand All @@ -622,7 +622,7 @@ define double @select_fcmp_nnan_nsz_ole_zero(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%lezero = fcmp ole double %x, 0.0
Expand All @@ -648,7 +648,7 @@ define double @select_fcmp_nnan_nsz_ule_zero(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%lezero = fcmp ule double %x, 0.0
Expand All @@ -661,7 +661,7 @@ define double @select_fcmp_nnan_nsz_ole_zero_unary_fneg(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero_unary_fneg(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%lezero = fcmp ole double %x, 0.0
Expand All @@ -676,7 +676,7 @@ define double @select_fcmp_nnan_nsz_ule_zero_unary_fneg(double %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero_unary_fneg(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[FABS]]
;
%lezero = fcmp ule double %x, 0.0
Expand All @@ -691,7 +691,7 @@ define float @select_fcmp_nnan_nsz_ole_negzero(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%lezero = fcmp ole float %x, -0.0
Expand Down Expand Up @@ -730,7 +730,7 @@ define float @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(float %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(
; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
; CHECK-NEXT: ret float [[FABS]]
;
%lezero = fcmp ole float %x, -0.0
Expand Down Expand Up @@ -802,7 +802,7 @@ define <2 x float> @select_fcmp_nnan_nsz_ugt_zero(<2 x float> %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero(
; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
; CHECK-NEXT: ret <2 x float> [[FABS]]
;
%gtzero = fcmp ugt <2 x float> %x, zeroinitializer
Expand Down Expand Up @@ -830,7 +830,7 @@ define <2 x float> @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(<2 x float> %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(
; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
; CHECK-NEXT: ret <2 x float> [[FABS]]
;
%gtzero = fcmp ugt <2 x float> %x, zeroinitializer
Expand All @@ -845,7 +845,7 @@ define half @select_fcmp_nnan_nsz_ogt_negzero(half %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_negzero(
; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast half [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[GTZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GTZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: ret half [[FABS]]
;
%gtzero = fcmp ogt half %x, -0.0
Expand All @@ -860,7 +860,7 @@ define half @select_fcmp_nnan_nsz_ugt_negzero(half %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_negzero(
; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt half [[X:%.*]], 0xH0000
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast half [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[GTZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: ret half [[FABS]]
;
%gtzero = fcmp ugt half %x, -0.0
Expand Down Expand Up @@ -890,7 +890,7 @@ define <2 x double> @select_fcmp_nnan_nsz_uge_zero(<2 x double> %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero(
; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
; CHECK-NEXT: ret <2 x double> [[FABS]]
;
%gezero = fcmp uge <2 x double> %x, zeroinitializer
Expand Down Expand Up @@ -918,7 +918,7 @@ define <2 x double> @select_fcmp_nnan_nsz_uge_zero_unary_fneg(<2 x double> %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero_unary_fneg(
; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
; CHECK-NEXT: ret <2 x double> [[FABS]]
;
%gezero = fcmp uge <2 x double> %x, zeroinitializer
Expand Down Expand Up @@ -948,7 +948,7 @@ define half @select_fcmp_nnan_nsz_uge_negzero(half %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero(
; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: ret half [[FABS]]
;
%gezero = fcmp uge half %x, -0.0
Expand Down Expand Up @@ -976,7 +976,7 @@ define half @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(half %x) {
; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(
; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
; CHECK-NEXT: ret half [[FABS]]
;
%gezero = fcmp uge half %x, -0.0
Expand Down
17 changes: 9 additions & 8 deletions llvm/test/Transforms/InstCombine/fneg-fabs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ define double @select_noFMF_nfabs_lt(double %x) {
; One test where the neg has fmfs.
define double @select_nsz_nfabs_lt_fmfProp(double %x) {
; CHECK-LABEL: @select_nsz_nfabs_lt_fmfProp(
; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = fcmp olt double %x, 0.000000e+00
Expand All @@ -32,8 +32,8 @@ define double @select_nsz_nfabs_lt_fmfProp(double %x) {

define double @select_nsz_nnan_nfabs_lt_fmfProp(double %x) {
; CHECK-LABEL: @select_nsz_nnan_nfabs_lt_fmfProp(
; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = fcmp olt double %x, 0.000000e+00
Expand Down Expand Up @@ -147,8 +147,9 @@ define double @select_noFMF_nfabs_gt(double %x) {
; One test where the neg has fmfs.
define double @select_nsz_nfabs_gt_fmfProp(double %x) {
; CHECK-LABEL: @select_nsz_nfabs_gt_fmfProp(
; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[X:%.*]], 0.000000e+00
; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
; CHECK-NEXT: [[SEL:%.*]] = select nsz i1 [[CMP]], double [[NEGX]], double [[X]]
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = fcmp ogt double %x, 0.000000e+00
Expand All @@ -159,8 +160,8 @@ define double @select_nsz_nfabs_gt_fmfProp(double %x) {

define double @select_nsz_nnan_nfabs_gt_fmfProp(double %x) {
; CHECK-LABEL: @select_nsz_nnan_nfabs_gt_fmfProp(
; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan ninf nsz double [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
; CHECK-NEXT: [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = fcmp ogt double %x, 0.000000e+00
Expand Down
Loading