Skip to content

Commit 93099c7

Browse files
committed
[InstCombine] allow more fast-math-flags to propagate in fneg-of-select fold
We were conservatively intersecting flags, but we can take the union here because forbidden special values (nsz/nnan/ninf) are not altered by fneg. So if they were guaranteed not present on the select or fneg, then they are guaranteed not present on the new select. Alive2 appears to agree on the test diffs (reduced to not include irrelevant flags like reassoc): https://alive2.llvm.org/ce/z/ViqqrO This prevents a potential regression if we tighten up the FMF behavior for fabs with NAN as suggested in issue #59279.
1 parent 8f1e11c commit 93099c7

File tree

2 files changed

+9
-5
lines changed

2 files changed

+9
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,14 +2408,18 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
24082408
Value *Cond;
24092409
if (match(Op, m_OneUse(m_Select(m_Value(Cond), m_Value(X), m_Value(Y))))) {
24102410
// Unlike most transforms, this one is not safe to propagate nsz unless
2411-
// it is present on the original select. (We are conservatively intersecting
2412-
// the nsz flags from the select and root fneg instruction.)
2411+
// it is present on the original select. We union the flags from the select
2412+
// and fneg and then remove nsz if needed.
24132413
auto propagateSelectFMF = [&](SelectInst *S, bool CommonOperand) {
24142414
S->copyFastMathFlags(&I);
2415-
if (auto *OldSel = dyn_cast<SelectInst>(Op))
2415+
if (auto *OldSel = dyn_cast<SelectInst>(Op)) {
2416+
FastMathFlags FMF = I.getFastMathFlags();
2417+
FMF |= OldSel->getFastMathFlags();
2418+
S->setFastMathFlags(FMF);
24162419
if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
24172420
!isGuaranteedNotToBeUndefOrPoison(OldSel->getCondition()))
24182421
S->setHasNoSignedZeros(false);
2422+
}
24192423
};
24202424
// -(Cond ? -P : Y) --> Cond ? P : -Y
24212425
Value *P;

llvm/test/Transforms/InstCombine/fneg.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ define float @select_fneg_true(float %x, float %y, i1 %b) {
629629
define <2 x float> @select_fneg_false(<2 x float> %x, <2 x float> %y, <2 x i1> %b) {
630630
; CHECK-LABEL: @select_fneg_false(
631631
; CHECK-NEXT: [[X_NEG:%.*]] = fneg nnan nsz <2 x float> [[X:%.*]]
632-
; CHECK-NEXT: [[R:%.*]] = select nnan <2 x i1> [[B:%.*]], <2 x float> [[X_NEG]], <2 x float> [[Y:%.*]]
632+
; CHECK-NEXT: [[R:%.*]] = select nnan ninf <2 x i1> [[B:%.*]], <2 x float> [[X_NEG]], <2 x float> [[Y:%.*]]
633633
; CHECK-NEXT: ret <2 x float> [[R]]
634634
;
635635
%ny = fneg nnan <2 x float> %y
@@ -772,7 +772,7 @@ define float @select_fneg_use1(float %x, float %y, i1 %b) {
772772
; CHECK-NEXT: [[NX:%.*]] = fneg ninf float [[X:%.*]]
773773
; CHECK-NEXT: call void @use(float [[NX]])
774774
; CHECK-NEXT: [[Y_NEG:%.*]] = fneg float [[Y:%.*]]
775-
; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], float [[X]], float [[Y_NEG]]
775+
; CHECK-NEXT: [[R:%.*]] = select fast i1 [[B:%.*]], float [[X]], float [[Y_NEG]]
776776
; CHECK-NEXT: ret float [[R]]
777777
;
778778
%nx = fneg ninf float %x

0 commit comments

Comments
 (0)