Skip to content

Commit c229cfe

Browse files
committedJul 26, 2019
[InstCombine] remove flop from lerp patterns
(Y * (1.0 - Z)) + (X * Z) --> Y - (Y * Z) + (X * Z) --> Y + Z * (X - Y) This is part of solving: https://bugs.llvm.org/show_bug.cgi?id=42716 Factoring eliminates an instruction, so that should be a good canonicalization. The potential conversion to FMA would be handled by the backend based on target capabilities. Differential Revision: https://reviews.llvm.org/D65305 llvm-svn: 367101
1 parent d93e8ec commit c229cfe

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed
 

‎llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1308,13 +1308,33 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
13081308
return Changed ? &I : nullptr;
13091309
}
13101310

1311+
/// Eliminate an op from a linear interpolation (lerp) pattern.
1312+
static Instruction *factorizeLerp(BinaryOperator &I,
1313+
InstCombiner::BuilderTy &Builder) {
1314+
Value *X, *Y, *Z;
1315+
if (!match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_Value(Y),
1316+
m_OneUse(m_FSub(m_FPOne(),
1317+
m_Value(Z))))),
1318+
m_OneUse(m_c_FMul(m_Value(X), m_Deferred(Z))))))
1319+
return nullptr;
1320+
1321+
// (Y * (1.0 - Z)) + (X * Z) --> Y + Z * (X - Y) [8 commuted variants]
1322+
Value *XY = Builder.CreateFSubFMF(X, Y, &I);
1323+
Value *MulZ = Builder.CreateFMulFMF(Z, XY, &I);
1324+
return BinaryOperator::CreateFAddFMF(Y, MulZ, &I);
1325+
}
1326+
13111327
/// Factor a common operand out of fadd/fsub of fmul/fdiv.
13121328
static Instruction *factorizeFAddFSub(BinaryOperator &I,
13131329
InstCombiner::BuilderTy &Builder) {
13141330
assert((I.getOpcode() == Instruction::FAdd ||
13151331
I.getOpcode() == Instruction::FSub) && "Expecting fadd/fsub");
13161332
assert(I.hasAllowReassoc() && I.hasNoSignedZeros() &&
13171333
"FP factorization requires FMF");
1334+
1335+
if (Instruction *Lerp = factorizeLerp(I, Builder))
1336+
return Lerp;
1337+
13181338
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
13191339
Value *X, *Y, *Z;
13201340
bool IsFMul;

‎llvm/test/Transforms/InstCombine/fadd-fsub-factor.ll

+24-32
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,9 @@ define float @fdiv_fsub_denorm(float %x) {
473473

474474
define float @lerp_commute0(float %a, float %b, float %c) {
475475
; CHECK-LABEL: @lerp_commute0(
476-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast float 1.000000e+00, [[C:%.*]]
477-
; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUB]], [[A:%.*]]
478-
; CHECK-NEXT: [[BC:%.*]] = fmul fast float [[C]], [[B:%.*]]
479-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], [[BC]]
476+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float [[B:%.*]], [[A:%.*]]
477+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float [[TMP1]], [[C:%.*]]
478+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[TMP2]], [[A]]
480479
; CHECK-NEXT: ret float [[ADD]]
481480
;
482481
%sub = fsub fast float 1.0, %c
@@ -488,10 +487,9 @@ define float @lerp_commute0(float %a, float %b, float %c) {
488487

489488
define <2 x float> @lerp_commute1(<2 x float> %a, <2 x float> %b, <2 x float> %c) {
490489
; CHECK-LABEL: @lerp_commute1(
491-
; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[C:%.*]]
492-
; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[A:%.*]]
493-
; CHECK-NEXT: [[BC:%.*]] = fmul <2 x float> [[C]], [[B:%.*]]
494-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast <2 x float> [[BC]], [[MUL]]
490+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <2 x float> [[B:%.*]], [[A:%.*]]
491+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <2 x float> [[TMP1]], [[C:%.*]]
492+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast <2 x float> [[TMP2]], [[A]]
495493
; CHECK-NEXT: ret <2 x float> [[ADD]]
496494
;
497495
%sub = fsub <2 x float> <float 1.0, float 1.0>, %c
@@ -503,10 +501,9 @@ define <2 x float> @lerp_commute1(<2 x float> %a, <2 x float> %b, <2 x float> %c
503501

504502
define float @lerp_commute2(float %a, float %b, float %c) {
505503
; CHECK-LABEL: @lerp_commute2(
506-
; CHECK-NEXT: [[SUB:%.*]] = fsub float 1.000000e+00, [[C:%.*]]
507-
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUB]], [[A:%.*]]
508-
; CHECK-NEXT: [[BC:%.*]] = fmul float [[B:%.*]], [[C]]
509-
; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[BC]]
504+
; CHECK-NEXT: [[TMP1:%.*]] = fsub reassoc nsz float [[B:%.*]], [[A:%.*]]
505+
; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[C:%.*]]
506+
; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[TMP2]], [[A]]
510507
; CHECK-NEXT: ret float [[ADD]]
511508
;
512509
%sub = fsub float 1.0, %c
@@ -518,10 +515,9 @@ define float @lerp_commute2(float %a, float %b, float %c) {
518515

519516
define float @lerp_commute3(float %a, float %b, float %c) {
520517
; CHECK-LABEL: @lerp_commute3(
521-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast float 1.000000e+00, [[C:%.*]]
522-
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUB]], [[A:%.*]]
523-
; CHECK-NEXT: [[BC:%.*]] = fmul float [[B:%.*]], [[C]]
524-
; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc ninf nsz float [[BC]], [[MUL]]
518+
; CHECK-NEXT: [[TMP1:%.*]] = fsub reassoc ninf nsz float [[B:%.*]], [[A:%.*]]
519+
; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc ninf nsz float [[TMP1]], [[C:%.*]]
520+
; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc ninf nsz float [[TMP2]], [[A]]
525521
; CHECK-NEXT: ret float [[ADD]]
526522
;
527523
%sub = fsub fast float 1.0, %c
@@ -533,10 +529,9 @@ define float @lerp_commute3(float %a, float %b, float %c) {
533529

534530
define double @lerp_commute4(double %a, double %b, double %c) {
535531
; CHECK-LABEL: @lerp_commute4(
536-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast double 1.000000e+00, [[C:%.*]]
537-
; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[SUB]], [[A:%.*]]
538-
; CHECK-NEXT: [[BC:%.*]] = fmul fast double [[C]], [[B:%.*]]
539-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast double [[MUL]], [[BC]]
532+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast double [[B:%.*]], [[A:%.*]]
533+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[C:%.*]]
534+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast double [[TMP2]], [[A]]
540535
; CHECK-NEXT: ret double [[ADD]]
541536
;
542537
%sub = fsub fast double 1.0, %c
@@ -548,10 +543,9 @@ define double @lerp_commute4(double %a, double %b, double %c) {
548543

549544
define double @lerp_commute5(double %a, double %b, double %c) {
550545
; CHECK-LABEL: @lerp_commute5(
551-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast double 1.000000e+00, [[C:%.*]]
552-
; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[SUB]], [[A:%.*]]
553-
; CHECK-NEXT: [[BC:%.*]] = fmul fast double [[C]], [[B:%.*]]
554-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast double [[BC]], [[MUL]]
546+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast double [[B:%.*]], [[A:%.*]]
547+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[C:%.*]]
548+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast double [[TMP2]], [[A]]
555549
; CHECK-NEXT: ret double [[ADD]]
556550
;
557551
%sub = fsub fast double 1.0, %c
@@ -563,10 +557,9 @@ define double @lerp_commute5(double %a, double %b, double %c) {
563557

564558
define half @lerp_commute6(half %a, half %b, half %c) {
565559
; CHECK-LABEL: @lerp_commute6(
566-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast half 0xH3C00, [[C:%.*]]
567-
; CHECK-NEXT: [[MUL:%.*]] = fmul fast half [[SUB]], [[A:%.*]]
568-
; CHECK-NEXT: [[BC:%.*]] = fmul fast half [[B:%.*]], [[C]]
569-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast half [[MUL]], [[BC]]
560+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast half [[B:%.*]], [[A:%.*]]
561+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast half [[TMP1]], [[C:%.*]]
562+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast half [[TMP2]], [[A]]
570563
; CHECK-NEXT: ret half [[ADD]]
571564
;
572565
%sub = fsub fast half 1.0, %c
@@ -578,10 +571,9 @@ define half @lerp_commute6(half %a, half %b, half %c) {
578571

579572
define half @lerp_commute7(half %a, half %b, half %c) {
580573
; CHECK-LABEL: @lerp_commute7(
581-
; CHECK-NEXT: [[SUB:%.*]] = fsub fast half 0xH3C00, [[C:%.*]]
582-
; CHECK-NEXT: [[MUL:%.*]] = fmul fast half [[SUB]], [[A:%.*]]
583-
; CHECK-NEXT: [[BC:%.*]] = fmul fast half [[B:%.*]], [[C]]
584-
; CHECK-NEXT: [[ADD:%.*]] = fadd fast half [[BC]], [[MUL]]
574+
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast half [[B:%.*]], [[A:%.*]]
575+
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast half [[TMP1]], [[C:%.*]]
576+
; CHECK-NEXT: [[ADD:%.*]] = fadd fast half [[TMP2]], [[A]]
585577
; CHECK-NEXT: ret half [[ADD]]
586578
;
587579
%sub = fsub fast half 1.0, %c

0 commit comments

Comments
 (0)