Skip to content

Commit fe9414d

Browse files
committed
[InstCombine] sink FP negation of operands through select
We don't always get this: Cond ? -X : -Y --> -(Cond ? X : Y) ...even with the legacy IR form of fneg in the case with extra uses, and we miss matching with the newer 'fneg' instruction because we are expecting binops through the rest of the path. Differential Revision: https://reviews.llvm.org/D61604 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360075 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 08fde8a commit fe9414d

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,18 @@ Instruction *InstCombiner::foldSelectOpOp(SelectInst &SI, Instruction *TI,
333333
TI->getType());
334334
}
335335

336+
// Cond ? -X : -Y --> -(Cond ? X : Y)
337+
Value *X, *Y;
338+
if (match(TI, m_FNeg(m_Value(X))) && match(FI, m_FNeg(m_Value(Y))) &&
339+
(TI->hasOneUse() || FI->hasOneUse())) {
340+
Value *NewSel = Builder.CreateSelect(Cond, X, Y, SI.getName() + ".v", &SI);
341+
// TODO: Remove the hack for the binop form when the unary op is optimized
342+
// properly with all IR passes.
343+
if (TI->getOpcode() != Instruction::FNeg)
344+
return BinaryOperator::CreateFNegFMF(NewSel, cast<BinaryOperator>(TI));
345+
return UnaryOperator::CreateFNeg(NewSel);
346+
}
347+
336348
// Only handle binary operators (including two-operand getelementptr) with
337349
// one-use here. As with the cast case above, it may be possible to relax the
338350
// one-use constraint, but that needs be examined carefully since it may not

test/Transforms/InstCombine/fneg.ll

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,8 @@ define <4 x double> @fdiv_op0_constant_fneg_vec(<4 x double> %x) {
161161

162162
define <2 x double> @fneg_fneg_sel(<2 x double> %x, <2 x double> %y, i1 %cond) {
163163
; CHECK-LABEL: @fneg_fneg_sel(
164-
; CHECK-NEXT: [[N1:%.*]] = fneg <2 x double> [[X:%.*]]
165-
; CHECK-NEXT: [[N2:%.*]] = fneg <2 x double> [[Y:%.*]]
166-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x double> [[N1]], <2 x double> [[N2]]
164+
; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], <2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]
165+
; CHECK-NEXT: [[SEL:%.*]] = fneg <2 x double> [[SEL_V]]
167166
; CHECK-NEXT: ret <2 x double> [[SEL]]
168167
;
169168
%n1 = fneg <2 x double> %x
@@ -178,8 +177,8 @@ define float @fneg_fneg_sel_extra_use1(float %x, float %y, i1 %cond) {
178177
; CHECK-LABEL: @fneg_fneg_sel_extra_use1(
179178
; CHECK-NEXT: [[N1:%.*]] = fneg float [[X:%.*]]
180179
; CHECK-NEXT: call void @use(float [[N1]])
181-
; CHECK-NEXT: [[N2:%.*]] = fneg float [[Y:%.*]]
182-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
180+
; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]
181+
; CHECK-NEXT: [[SEL:%.*]] = fneg float [[SEL_V]]
183182
; CHECK-NEXT: ret float [[SEL]]
184183
;
185184
%n1 = fneg float %x
@@ -191,10 +190,10 @@ define float @fneg_fneg_sel_extra_use1(float %x, float %y, i1 %cond) {
191190

192191
define float @fneg_fneg_sel_extra_use2(float %x, float %y, i1 %cond) {
193192
; CHECK-LABEL: @fneg_fneg_sel_extra_use2(
194-
; CHECK-NEXT: [[N1:%.*]] = fneg float [[X:%.*]]
195193
; CHECK-NEXT: [[N2:%.*]] = fneg float [[Y:%.*]]
196194
; CHECK-NEXT: call void @use(float [[N2]])
197-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
195+
; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X:%.*]], float [[Y]]
196+
; CHECK-NEXT: [[SEL:%.*]] = fneg float [[SEL_V]]
198197
; CHECK-NEXT: ret float [[SEL]]
199198
;
200199
%n1 = fneg float %x
@@ -210,8 +209,8 @@ define float @fsub_fsub_sel_extra_use1(float %x, float %y, i1 %cond) {
210209
; CHECK-LABEL: @fsub_fsub_sel_extra_use1(
211210
; CHECK-NEXT: [[N1:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
212211
; CHECK-NEXT: call void @use(float [[N1]])
213-
; CHECK-NEXT: [[N2:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
214-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
212+
; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]
213+
; CHECK-NEXT: [[SEL:%.*]] = fsub float -0.000000e+00, [[SEL_V]]
215214
; CHECK-NEXT: ret float [[SEL]]
216215
;
217216
%n1 = fsub float -0.0, %x

0 commit comments

Comments
 (0)