[PATCH] D131672: [instcombine] Optimise for zero initialisation of product given finite math in Clang

Zain Jaffal via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 15 03:26:34 PDT 2022


zjaffal updated this revision to Diff 452620.
zjaffal added a comment.

- Move functionality to `InstCombineMulDivRem.cpp`
- Use `matchSimpleRecurrence`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131672/new/

https://reviews.llvm.org/D131672

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
  llvm/test/Transforms/InstCombine/remove-loop-phi-fastmul.ll


Index: llvm/test/Transforms/InstCombine/remove-loop-phi-fastmul.ll
===================================================================
--- llvm/test/Transforms/InstCombine/remove-loop-phi-fastmul.ll
+++ llvm/test/Transforms/InstCombine/remove-loop-phi-fastmul.ll
@@ -6,15 +6,11 @@
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[I_02:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT:    [[F_PROD_01:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[MUL:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [1000 x double], ptr [[ARR_D:%.*]], i64 0, i64 [[I_02]]
-; CHECK-NEXT:    [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8
-; CHECK-NEXT:    [[MUL]] = fmul fast double [[F_PROD_01]], [[TMP0]]
 ; CHECK-NEXT:    [[INC]] = add i64 [[I_02]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], 1000
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[END:%.*]]
 ; CHECK:       end:
-; CHECK-NEXT:    ret double [[MUL]]
+; CHECK-NEXT:    ret double 0.000000e+00
 ;
 entry:
   br label %for.body
@@ -142,15 +138,11 @@
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[I_02:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT:    [[F_PROD_01:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[MUL:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [1000 x double], ptr [[ARR_D:%.*]], i64 0, i64 [[I_02]]
-; CHECK-NEXT:    [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8
-; CHECK-NEXT:    [[MUL]] = fmul fast double [[F_PROD_01]], [[TMP0]]
 ; CHECK-NEXT:    [[INC]] = add i64 [[I_02]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], 1000
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[END:%.*]]
 ; CHECK:       end:
-; CHECK-NEXT:    ret double [[MUL]]
+; CHECK-NEXT:    ret double 0.000000e+00
 ;
 entry:
   %entry_val = fmul fast double %entry_const, 0.0
Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
@@ -139,6 +140,15 @@
   return nullptr;
 }
 
+bool phiAllConstantOperandsAreZero(PHINode &PN) {
+  size_t ZeroConstCount = 0;
+  for (Value *V : PN.operands())
+    if (Constant *ConstVA = dyn_cast<Constant>(V))
+      if (ConstVA->isZeroValue())
+        ZeroConstCount += 1;
+  return ZeroConstCount == PN.getNumOperands() - 1;
+}
+
 Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
   if (Value *V = simplifyMulInst(I.getOperand(0), I.getOperand(1),
                                  SQ.getWithInstruction(&I)))
@@ -483,6 +493,16 @@
   if (Instruction *R = foldFPSignBitOps(I))
     return R;
 
+  PHINode *PN = nullptr;
+  Value *Start = nullptr, *Step = nullptr;
+  if (matchSimpleRecurrence(&I, PN, Start, Step) && I.hasNoInfs() &&
+      I.hasNoNaNs() && I.hasNoSignedZeros()) {
+    if (phiAllConstantOperandsAreZero(*PN)) {
+      auto *ZeroVal = Constant::getNullValue(I.getType());
+      return replaceInstUsesWith(I, ZeroVal);
+    }
+  }
+
   // X * -1.0 --> -X
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   if (match(Op1, m_SpecificFP(-1.0)))
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -6502,7 +6502,8 @@
     case Instruction::Sub:
     case Instruction::And:
     case Instruction::Or:
-    case Instruction::Mul: {
+    case Instruction::Mul:
+    case Instruction::FMul: {
       Value *LL = LU->getOperand(0);
       Value *LR = LU->getOperand(1);
       // Find a recurrence.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131672.452620.patch
Type: text/x-patch
Size: 4106 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220815/b627965c/attachment.bin>


More information about the llvm-commits mailing list