-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] Fold fneg over select #89947
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesAs we folds fabs over select in #86390, this patch folds fneg over select to make sure nabs idioms are generated. Alive2 for FMF propagation: https://alive2.llvm.org/ce/z/-h6Vuo Full diff: https://github.com/llvm/llvm-project/pull/89947.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 88b7e496897e1f..ea2cdadc84f143 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2781,6 +2781,16 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
propagateSelectFMF(NewSel, P == X);
return NewSel;
}
+
+ // -(Cond ? X : C) --> Cond ? -X : -C
+ // -(Cond ? C : Y) --> Cond ? -C : -Y
+ if (match(X, m_ImmConstant()) || match(Y, m_ImmConstant())) {
+ Value *NegX = Builder.CreateFNegFMF(X, &I, X->getName() + ".neg");
+ Value *NegY = Builder.CreateFNegFMF(Y, &I, Y->getName() + ".neg");
+ SelectInst *NewSel = SelectInst::Create(Cond, NegX, NegY);
+ propagateSelectFMF(NewSel, /*CommonOperand=*/true);
+ return NewSel;
+ }
}
// fneg (copysign x, y) -> copysign x, (fneg y)
diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 7c9289c447113f..3c4088832feaaa 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -980,7 +980,7 @@ define float @fneg_ldexp_contract(float %x, i32 %n) {
define float @fneg_ldexp_metadata(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_metadata(
; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]]
-; CHECK-NEXT: [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]]), !arst !0
+; CHECK-NEXT: [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]]), !arst [[META0:![0-9]+]]
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n), !arst !0
@@ -988,4 +988,125 @@ define float @fneg_ldexp_metadata(float %x, i32 %n) {
ret float %neg
}
+define float @test_fneg_select_constants(i1 %cond) {
+; CHECK-LABEL: @test_fneg_select_constants(
+; CHECK-NEXT: [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float 0.000000e+00
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float 0.0, float -0.0
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+define <2 x float> @test_fneg_vec(<2 x i1> %cond) {
+; CHECK-LABEL: @test_fneg_vec(
+; CHECK-NEXT: [[NEG:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> <float -0.000000e+00, float 0.000000e+00>, <2 x float> <float 0.000000e+00, float -0.000000e+00>
+; CHECK-NEXT: ret <2 x float> [[NEG]]
+;
+ %sel1 = select <2 x i1> %cond, <2 x float> <float 0.0, float -0.0>, <2 x float> <float -0.0, float 0.0>
+ %neg = fneg <2 x float> %sel1
+ ret <2 x float> %neg
+}
+
+define float @test_fneg_select_var_constant(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_var_constant(
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = select i1 [[COND:%.*]], float [[X_NEG]], float 0.000000e+00
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float %x, float -0.0
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+; nsz can be preserved.
+
+define float @test_fneg_select_var_constant_fmf1(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_var_constant_fmf1(
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], float [[X_NEG]], float -1.000000e+00
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select nnan ninf nsz i1 %cond, float %x, float 1.0
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+define float @test_fneg_select_var_constant_fmf2(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_var_constant_fmf2(
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], float [[X_NEG]], float -1.000000e+00
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float %x, float 1.0
+ %neg = fneg nnan ninf nsz float %sel1
+ ret float %neg
+}
+
+define float @test_fneg_select_constant_var(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_constant_var(
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[X_NEG]]
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float 0.0, float %x
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+; Make sure nabs is generated.
+
+define float @test_fneg_select_abs(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_abs(
+; CHECK-NEXT: [[ABSX:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
+; CHECK-NEXT: [[ABSX_NEG:%.*]] = fneg float [[ABSX]]
+; CHECK-NEXT: [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[ABSX_NEG]]
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %absx = call float @llvm.fabs.f32(float %x)
+ %sel1 = select i1 %cond, float 0.0, float %absx
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+define float @test_fneg_fabs_select(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_fabs_select(
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[DOTNEG]]
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float 0.0, float %x
+ %abs = call float @llvm.fabs.f32(float %sel1)
+ %neg = fneg float %abs
+ ret float %neg
+}
+
+define float @test_fneg_select_constant_var_multiuse(i1 %cond, float %x) {
+; CHECK-LABEL: @test_fneg_select_constant_var_multiuse(
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND:%.*]], float 0.000000e+00, float [[X:%.*]]
+; CHECK-NEXT: call void @use(float [[SEL1]])
+; CHECK-NEXT: [[NEG:%.*]] = fneg float [[SEL1]]
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %sel1 = select i1 %cond, float 0.0, float %x
+ call void @use(float %sel1)
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
+; Don't break fmax idioms.
+
+define float @test_fneg_select_maxnum(float %x) {
+; CHECK-LABEL: @test_fneg_select_maxnum(
+; CHECK-NEXT: [[SEL1:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
+; CHECK-NEXT: [[NEG:%.*]] = fneg float [[SEL1]]
+; CHECK-NEXT: ret float [[NEG]]
+;
+ %cmp1 = fcmp ogt float %x, 1.0
+ %sel1 = select nnan nsz i1 %cmp1, float %x, float 1.0
+ %neg = fneg float %sel1
+ ret float %neg
+}
+
!0 = !{}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index a7d01b4f824db0..e4fb7764ba9e53 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -364,8 +364,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__select_chain_inf_nan_1(i1 %cond,
define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_ninf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_ninf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: ret float [[FABS]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: ret float [[TMP1]]
;
%select = select i1 %cond, float %x, float 0xFFF0000000000000
%fabs = call float @llvm.fabs.f32(float %select)
@@ -376,8 +376,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_ninf_rhs(i1 %cond, f
define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: ret float [[FABS]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: ret float [[TMP1]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fabs = call float @llvm.fabs.f32(float %select)
@@ -400,8 +400,8 @@ define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__fabs_
define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_no_positives__fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: ret float [[FABS]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: ret float [[TMP1]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fabs = call float @llvm.fabs.f32(float %select)
@@ -435,8 +435,8 @@ define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_no_positives_na
define nofpclass(inf) float @ret_nofpclass_inf__fneg_select_ninf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fneg_select_ninf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]
-; CHECK-NEXT: ret float [[FNEG]]
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]
+; CHECK-NEXT: ret float [[X_NEG]]
;
%select = select i1 %cond, float %x, float 0xFFF0000000000000
%fneg = fneg float %select
@@ -447,8 +447,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__fneg_select_ninf_rhs(i1 %cond, f
define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___fneg_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_nofpclass_nonegatives_noinf___fneg_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]
-; CHECK-NEXT: ret float [[FNEG]]
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]
+; CHECK-NEXT: ret float [[X_NEG]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fneg = fneg float %select
@@ -459,8 +459,8 @@ define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___
define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___fneg_select_ninf_lhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_nofpclass_nonegatives_noinf___fneg_select_ninf_lhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]
-; CHECK-NEXT: ret float [[FNEG]]
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]
+; CHECK-NEXT: ret float [[X_NEG]]
;
%select = select i1 %cond, float 0xFFF0000000000000, float %x
%fneg = fneg float %select
@@ -470,8 +470,8 @@ define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___
define nofpclass(pzero psub pnorm pinf) float @ret_nofpclass_nopositives___fneg_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives___fneg_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[SELECT]]
+; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]
+; CHECK-NEXT: [[FNEG:%.*]] = select i1 [[COND]], float [[X_NEG]], float 0xFFF0000000000000
; CHECK-NEXT: ret float [[FNEG]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -483,9 +483,9 @@ define nofpclass(pzero psub pnorm pinf) float @ret_nofpclass_nopositives___fneg_
define nofpclass(inf) float @ret_nofpclass_inf__fneg_fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fneg_fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT: ret float [[FNEG]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: ret float [[DOTNEG]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fabs = call float @llvm.fabs.f32(float %select)
@@ -497,9 +497,9 @@ define nofpclass(inf) float @ret_nofpclass_inf__fneg_fabs_select_pinf_rhs(i1 %co
define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives__fneg_fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives__fneg_fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT: ret float [[FNEG]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: ret float [[DOTNEG]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fabs = call float @llvm.fabs.f32(float %select)
@@ -535,8 +535,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__copysign_unknown_select_pinf_rhs
define nofpclass(inf) float @ret_nofpclass_inf__copysign_positive_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_positive_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: ret float [[COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: ret float [[TMP1]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%copysign = call float @llvm.copysign.f32(float %select, float 1.0)
@@ -547,8 +547,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__copysign_negative_select_pinf_rh
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_negative_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]
-; CHECK-NEXT: ret float [[COPYSIGN]]
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: ret float [[DOTNEG]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%copysign = call float @llvm.copysign.f32(float %select, float -1.0)
@@ -627,8 +627,8 @@ define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_non
define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_nopositives__copysign_fabs_select_pinf_rhs(i1 %cond, float %x, float %sign) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives__copysign_fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[SIGN:%.*]]) {
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: ret float [[COPYSIGN]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: ret float [[TMP1]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
%fabs.sign = call float @llvm.fabs.f32(float %sign)
@@ -678,9 +678,9 @@ define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__copys
define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[TMP2]], float 0x7FF0000000000000
-; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[DOTNEG]], float 0xFFF0000000000000
; CHECK-NEXT: ret float [[COPYSIGN]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -705,9 +705,9 @@ define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_no
define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[TMP2]], float 0x7FF0000000000000
-; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[DOTNEG]], float 0xFFF0000000000000
; CHECK-NEXT: ret float [[COPYSIGN]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
|
SelectInst *NewSel = SelectInst::Create(Cond, NegX, NegY); | ||
propagateSelectFMF(NewSel, /*CommonOperand=*/true); | ||
return NewSel; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use FoldOpIntoSelect here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. FoldOpIntoSelect
doesn't propagate FMF flags from fneg to select.
See #86390. nsz
flag is not always safe to be propagated. So they would be better to be handled separately.
As we folds fabs over select in #86390, this patch folds fneg over select to make sure nabs idioms are generated.
Addresses #86390 (comment).
Alive2 for FMF propagation: https://alive2.llvm.org/ce/z/-h6Vuo