[llvm] f9d8e33 - [SCCP] Turn sext into zext for non-negative ranges.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 19 02:19:12 PDT 2020


Author: Florian Hahn
Date: 2020-06-19T10:17:55+01:00
New Revision: f9d8e33c324de95f868dbe50d0e1e475ef2d3beb

URL: https://github.com/llvm/llvm-project/commit/f9d8e33c324de95f868dbe50d0e1e475ef2d3beb
DIFF: https://github.com/llvm/llvm-project/commit/f9d8e33c324de95f868dbe50d0e1e475ef2d3beb.diff

LOG: [SCCP] Turn sext into zext for non-negative ranges.

This patch updates SCCP/IPSCCP to use the computed range info to turn
sexts into zexts, if the value is known to be non-negative. We already
to a similar transform in CorrelatedValuePropagation, but it seems like
we can catch a lot of additional cases by doing it in SCCP/IPSCCP as
well.

The transform is limited to ranges that are known to not include undef.

Currently constant ranges from conditions are treated as potentially
containing undef, due to PR46144. Once we flip this, the transform will
be more effective in practice.

Reviewers: efriedma, davide

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D81756

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/SCCP.cpp
    llvm/test/Transforms/SCCP/ip-ranges-casts.ll
    llvm/test/Transforms/SCCP/ip-ranges-sext.ll
    llvm/test/Transforms/SCCP/ranges-sext.ll
    llvm/test/Transforms/SCCP/widening.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index ccfc0b844c30..432a5ef03cdc 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -67,10 +67,15 @@ using namespace llvm;
 
 STATISTIC(NumInstRemoved, "Number of instructions removed");
 STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
+STATISTIC(NumInstReplaced,
+          "Number of instructions replaced with (simpler) instruction");
 
 STATISTIC(IPNumInstRemoved, "Number of instructions removed by IPSCCP");
 STATISTIC(IPNumArgsElimed ,"Number of arguments constant propagated by IPSCCP");
 STATISTIC(IPNumGlobalConst, "Number of globals found to be constant by IPSCCP");
+STATISTIC(
+    IPNumInstReplaced,
+    "Number of instructions replaced with (simpler) instruction by IPSCCP");
 
 // The maximum number of range extensions allowed for operations requiring
 // widening.
@@ -283,6 +288,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
     return StructValues;
   }
 
+  void removeLatticeValueFor(Value *V) { ValueState.erase(V); }
+
   const ValueLatticeElement &getLatticeValueFor(Value *V) const {
     assert(!V->getType()->isStructTy() &&
            "Should use getStructLatticeValueFor");
@@ -1607,7 +1614,9 @@ static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
 }
 
 static bool simplifyInstsInBlock(SCCPSolver &Solver, BasicBlock &BB,
-                                 Statistic &InstRemovedStat) {
+                                 SmallPtrSetImpl<Value *> &InsertedValues,
+                                 Statistic &InstRemovedStat,
+                                 Statistic &InstReplacedStat) {
   bool MadeChanges = false;
   for (Instruction &Inst : make_early_inc_range(BB)) {
     if (Inst.getType()->isVoidTy())
@@ -1618,6 +1627,22 @@ static bool simplifyInstsInBlock(SCCPSolver &Solver, BasicBlock &BB,
       // Hey, we just changed something!
       MadeChanges = true;
       ++InstRemovedStat;
+    } else if (isa<SExtInst>(&Inst)) {
+      Value *ExtOp = Inst.getOperand(0);
+      if (isa<Constant>(ExtOp) || InsertedValues.count(ExtOp))
+        continue;
+      const ValueLatticeElement &IV = Solver.getLatticeValueFor(ExtOp);
+      if (!IV.isConstantRange(/*UndefAllowed=*/false))
+        continue;
+      if (IV.getConstantRange().isAllNonNegative()) {
+        auto *ZExt = new ZExtInst(ExtOp, Inst.getType(), "", &Inst);
+        InsertedValues.insert(ZExt);
+        Inst.replaceAllUsesWith(ZExt);
+        Solver.removeLatticeValueFor(&Inst);
+        Inst.eraseFromParent();
+        InstReplacedStat++;
+        MadeChanges = true;
+      }
     }
   }
   return MadeChanges;
@@ -1653,6 +1678,7 @@ static bool runSCCP(Function &F, const DataLayout &DL,
   // delete their contents now.  Note that we cannot actually delete the blocks,
   // as we cannot modify the CFG of the function.
 
+  SmallPtrSet<Value *, 32> InsertedValues;
   for (BasicBlock &BB : F) {
     if (!Solver.isBlockExecutable(&BB)) {
       LLVM_DEBUG(dbgs() << "  BasicBlock Dead:" << BB);
@@ -1664,7 +1690,8 @@ static bool runSCCP(Function &F, const DataLayout &DL,
       continue;
     }
 
-    MadeChanges |= simplifyInstsInBlock(Solver, BB, NumInstRemoved);
+    MadeChanges |= simplifyInstsInBlock(Solver, BB, InsertedValues,
+                                        NumInstRemoved, NumInstReplaced);
   }
 
   return MadeChanges;
@@ -1893,6 +1920,7 @@ bool llvm::runIPSCCP(
         }
       }
 
+    SmallPtrSet<Value *, 32> InsertedValues;
     for (BasicBlock &BB : F) {
       if (!Solver.isBlockExecutable(&BB)) {
         LLVM_DEBUG(dbgs() << "  BasicBlock Dead:" << BB);
@@ -1905,7 +1933,8 @@ bool llvm::runIPSCCP(
         continue;
       }
 
-      MadeChanges |= simplifyInstsInBlock(Solver, BB, IPNumInstRemoved);
+      MadeChanges |= simplifyInstsInBlock(Solver, BB, InsertedValues,
+                                          IPNumInstRemoved, IPNumInstReplaced);
     }
 
     DomTreeUpdater DTU = Solver.getDTU(F);

diff  --git a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
index c7a53c118977..b39f2985b8a3 100644
--- a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
+++ b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
@@ -109,9 +109,9 @@ define i1 @caller.zext() {
 ; x = [100, 301)
 define internal i1 @f.sext(i32 %x, i32 %y) {
 ; CHECK-LABEL: define internal i1 @f.sext(i32 %x, i32 %y) {
-; CHECK-NEXT:    %t.1 = sext i32 %x to i64
-; CHECK-NEXT:    %c.2 = icmp sgt i64 %t.1, 299
-; CHECK-NEXT:    %c.4 = icmp slt i64 %t.1, 101
+; CHECK-NEXT:    [[T_1:%.*]] = zext i32 %x to i64
+; CHECK-NEXT:    %c.2 = icmp sgt i64 [[T_1]], 299
+; CHECK-NEXT:    %c.4 = icmp slt i64 [[T_1]], 101
 ; CHECK-NEXT:    %res.1 = add i1 false, %c.2
 ; CHECK-NEXT:    %res.2 = add i1 %res.1, false
 ; CHECK-NEXT:    %res.3 = add i1 %res.2, %c.4

diff  --git a/llvm/test/Transforms/SCCP/ip-ranges-sext.ll b/llvm/test/Transforms/SCCP/ip-ranges-sext.ll
index eeac47ae572e..aef562cfdb51 100644
--- a/llvm/test/Transforms/SCCP/ip-ranges-sext.ll
+++ b/llvm/test/Transforms/SCCP/ip-ranges-sext.ll
@@ -105,8 +105,8 @@ exit:
 define i64 @test5(i32 %x) {
 ; CHECK-LABEL: @test5(
 ; CHECK-NEXT:    [[P:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[EXT:%.*]] = sext i32 [[P]] to i64
-; CHECK-NEXT:    ret i64 [[EXT]]
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[P]] to i64
+; CHECK-NEXT:    ret i64 [[TMP1]]
 ;
   %p = and i32 %x, 15
   %ext = sext i32 %p to i64
@@ -126,8 +126,8 @@ define i64 @test6(i32 %x) {
 define i64 @test7(i16 %x) {
 ; CHECK-LABEL: @test7(
 ; CHECK-NEXT:    [[P:%.*]] = and i16 [[X:%.*]], 15
-; CHECK-NEXT:    [[EXT_1:%.*]] = sext i16 [[P]] to i32
-; CHECK-NEXT:    [[EXT_2:%.*]] = sext i32 [[EXT_1]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i16 [[P]] to i32
+; CHECK-NEXT:    [[EXT_2:%.*]] = sext i32 [[TMP1]] to i64
 ; CHECK-NEXT:    ret i64 [[EXT_2]]
 ;
   %p = and i16 %x, 15

diff  --git a/llvm/test/Transforms/SCCP/ranges-sext.ll b/llvm/test/Transforms/SCCP/ranges-sext.ll
index 66e9e52c0441..75e070b01621 100644
--- a/llvm/test/Transforms/SCCP/ranges-sext.ll
+++ b/llvm/test/Transforms/SCCP/ranges-sext.ll
@@ -35,8 +35,8 @@ exit:
 define i64 @test2(i32 %x) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:    [[P:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[EXT:%.*]] = sext i32 [[P]] to i64
-; CHECK-NEXT:    ret i64 [[EXT]]
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[P]] to i64
+; CHECK-NEXT:    ret i64 [[TMP1]]
 ;
   %p = and i32 %x, 15
   %ext = sext i32 %p to i64
@@ -54,8 +54,8 @@ define i64 @test3(i1 %c.1, i1 %c.2) {
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[TRUE_1]] ], [ 1, [[TRUE_2]] ], [ 3, [[FALSE]] ]
-; CHECK-NEXT:    [[EXT:%.*]] = sext i32 [[P]] to i64
-; CHECK-NEXT:    ret i64 [[EXT]]
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[P]] to i64
+; CHECK-NEXT:    ret i64 [[TMP1]]
 ;
   br i1 %c.1, label %true.1, label %false
 

diff  --git a/llvm/test/Transforms/SCCP/widening.ll b/llvm/test/Transforms/SCCP/widening.ll
index 825175882b1e..2703bdb27dff 100644
--- a/llvm/test/Transforms/SCCP/widening.ll
+++ b/llvm/test/Transforms/SCCP/widening.ll
@@ -451,7 +451,7 @@ define void @foo(i64* %arg) {
 ; SCCP-NEXT:    [[TMP7:%.*]] = sub i64 3, [[TMP6]]
 ; SCCP-NEXT:    [[TMP8:%.*]] = shl i64 [[TMP7]], 1
 ; SCCP-NEXT:    [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
-; SCCP-NEXT:    [[TMP10:%.*]] = sext i32 [[TMP9]] to i64
+; SCCP-NEXT:    [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
 ; SCCP-NEXT:    br label [[BB11:%.*]]
 ; SCCP:       bb11:
 ; SCCP-NEXT:    [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
@@ -489,7 +489,7 @@ define void @foo(i64* %arg) {
 ; IPSCCP-NEXT:    [[TMP7:%.*]] = sub i64 3, [[TMP6]]
 ; IPSCCP-NEXT:    [[TMP8:%.*]] = shl i64 [[TMP7]], 1
 ; IPSCCP-NEXT:    [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
-; IPSCCP-NEXT:    [[TMP10:%.*]] = sext i32 [[TMP9]] to i64
+; IPSCCP-NEXT:    [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
 ; IPSCCP-NEXT:    br label [[BB11:%.*]]
 ; IPSCCP:       bb11:
 ; IPSCCP-NEXT:    [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]


        


More information about the llvm-commits mailing list