llvm.org GIT mirror llvm / fe9414d
[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 Sanjay Patel 1 year, 5 months ago
2 changed file(s) with 20 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
330330 SI.getName() + ".v", &SI);
331331 return CastInst::Create(Instruction::CastOps(TI->getOpcode()), NewSI,
332332 TI->getType());
333 }
334
335 // Cond ? -X : -Y --> -(Cond ? X : Y)
336 Value *X, *Y;
337 if (match(TI, m_FNeg(m_Value(X))) && match(FI, m_FNeg(m_Value(Y))) &&
338 (TI->hasOneUse() || FI->hasOneUse())) {
339 Value *NewSel = Builder.CreateSelect(Cond, X, Y, SI.getName() + ".v", &SI);
340 // TODO: Remove the hack for the binop form when the unary op is optimized
341 // properly with all IR passes.
342 if (TI->getOpcode() != Instruction::FNeg)
343 return BinaryOperator::CreateFNegFMF(NewSel, cast(TI));
344 return UnaryOperator::CreateFNeg(NewSel);
333345 }
334346
335347 // Only handle binary operators (including two-operand getelementptr) with
160160
161161 define <2 x double> @fneg_fneg_sel(<2 x double> %x, <2 x double> %y, i1 %cond) {
162162 ; CHECK-LABEL: @fneg_fneg_sel(
163 ; CHECK-NEXT: [[N1:%.*]] = fneg <2 x double> [[X:%.*]]
164 ; CHECK-NEXT: [[N2:%.*]] = fneg <2 x double> [[Y:%.*]]
165 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x double> [[N1]], <2 x double> [[N2]]
163 ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], <2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]
164 ; CHECK-NEXT: [[SEL:%.*]] = fneg <2 x double> [[SEL_V]]
166165 ; CHECK-NEXT: ret <2 x double> [[SEL]]
167166 ;
168167 %n1 = fneg <2 x double> %x
177176 ; CHECK-LABEL: @fneg_fneg_sel_extra_use1(
178177 ; CHECK-NEXT: [[N1:%.*]] = fneg float [[X:%.*]]
179178 ; CHECK-NEXT: call void @use(float [[N1]])
180 ; CHECK-NEXT: [[N2:%.*]] = fneg float [[Y:%.*]]
181 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
179 ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]
180 ; CHECK-NEXT: [[SEL:%.*]] = fneg float [[SEL_V]]
182181 ; CHECK-NEXT: ret float [[SEL]]
183182 ;
184183 %n1 = fneg float %x
190189
191190 define float @fneg_fneg_sel_extra_use2(float %x, float %y, i1 %cond) {
192191 ; CHECK-LABEL: @fneg_fneg_sel_extra_use2(
193 ; CHECK-NEXT: [[N1:%.*]] = fneg float [[X:%.*]]
194192 ; CHECK-NEXT: [[N2:%.*]] = fneg float [[Y:%.*]]
195193 ; CHECK-NEXT: call void @use(float [[N2]])
196 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
194 ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X:%.*]], float [[Y]]
195 ; CHECK-NEXT: [[SEL:%.*]] = fneg float [[SEL_V]]
197196 ; CHECK-NEXT: ret float [[SEL]]
198197 ;
199198 %n1 = fneg float %x
209208 ; CHECK-LABEL: @fsub_fsub_sel_extra_use1(
210209 ; CHECK-NEXT: [[N1:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
211210 ; CHECK-NEXT: call void @use(float [[N1]])
212 ; CHECK-NEXT: [[N2:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
213 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]
211 ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]
212 ; CHECK-NEXT: [[SEL:%.*]] = fsub float -0.000000e+00, [[SEL_V]]
214213 ; CHECK-NEXT: ret float [[SEL]]
215214 ;
216215 %n1 = fsub float -0.0, %x