[llvm-branch-commits] [llvm] 4ad4190 - [GVN] Correctly set modified status when doing PRE on indices.

Florian Hahn via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Dec 27 14:04:01 PST 2020


Author: Florian Hahn
Date: 2020-12-27T21:58:31Z
New Revision: 4ad41902e8c7481ccf3cdf6e618dfcd1e1fc10fc

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

LOG: [GVN] Correctly set modified status when doing PRE on indices.

This patch updates GVN to correctly return the modified status, if PRE
is performed on indices. It fixes a crash when building the test-suite
with EXPENSIVE_CHECKS and LTO.

Added: 
    llvm/test/Transforms/GVN/PRE/modified-status.ll

Modified: 
    llvm/lib/Transforms/Scalar/GVN.cpp
    llvm/test/Transforms/GVN/PRE/pre-gep-load.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 5d37eb73f9b1..30d00758c662 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1472,13 +1472,14 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
     return false;
   }
 
+  bool Changed = false;
   // If this load follows a GEP, see if we can PRE the indices before analyzing.
   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0))) {
     for (GetElementPtrInst::op_iterator OI = GEP->idx_begin(),
                                         OE = GEP->idx_end();
          OI != OE; ++OI)
       if (Instruction *I = dyn_cast<Instruction>(OI->get()))
-        performScalarPRE(I);
+        Changed |= performScalarPRE(I);
   }
 
   // Step 2: Analyze the availability of the load
@@ -1489,7 +1490,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
   // If we have no predecessors that produce a known value for this load, exit
   // early.
   if (ValuesPerBlock.empty())
-    return false;
+    return Changed;
 
   // Step 3: Eliminate fully redundancy.
   //
@@ -1521,12 +1522,12 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
 
   // Step 4: Eliminate partial redundancy.
   if (!isPREEnabled() || !isLoadPREEnabled())
-    return false;
+    return Changed;
   if (!isLoadInLoopPREEnabled() && this->LI &&
       this->LI->getLoopFor(LI->getParent()))
-    return false;
+    return Changed;
 
-  return PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks);
+  return Changed || PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks);
 }
 
 static bool impliesEquivalanceIfTrue(CmpInst* Cmp) {

diff  --git a/llvm/test/Transforms/GVN/PRE/modified-status.ll b/llvm/test/Transforms/GVN/PRE/modified-status.ll
new file mode 100644
index 000000000000..6a329db51d7c
--- /dev/null
+++ b/llvm/test/Transforms/GVN/PRE/modified-status.ll
@@ -0,0 +1,60 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -gvn -S %s | FileCheck %s
+
+; Make sure GVN correctly sets the modified status when doing PRE.
+
+define i32 @test(i64 %v, i32* %ptr.1, i32** %ptr.2, i1 %c)  {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L_0:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    ret i32 10
+; CHECK:       if.end:
+; CHECK-NEXT:    [[L_0_EXT:%.*]] = zext i32 [[L_0]] to i64
+; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i64 [[L_0_EXT]], 10
+; CHECK-NEXT:    br i1 [[C_2]], label [[IF_2_END:%.*]], label [[IF_2_THEN:%.*]]
+; CHECK:       if.2.then:
+; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[PTR_1]], i64 [[V:%.*]]
+; CHECK-NEXT:    [[L_2:%.*]] = load i32, i32* [[GEP_1]], align 4
+; CHECK-NEXT:    [[DOTPRE:%.*]] = zext i32 [[L_2]] to i64
+; CHECK-NEXT:    br label [[IF_2_END]]
+; CHECK:       if.2.end:
+; CHECK-NEXT:    [[REP_0_EXT_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], [[IF_2_THEN]] ], [ 10, [[IF_END]] ]
+; CHECK-NEXT:    [[REP_0:%.*]] = phi i32 [ [[L_2]], [[IF_2_THEN]] ], [ [[L_0]], [[IF_END]] ]
+; CHECK-NEXT:    [[L_3:%.*]] = load i32*, i32** [[PTR_2:%.*]], align 8
+; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[PTR_1]], i64 [[REP_0_EXT_PRE_PHI]]
+; CHECK-NEXT:    [[L_4:%.*]] = load i32, i32* [[GEP_2]], align 4
+; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[L_3]], i64 10
+; CHECK-NEXT:    [[L_5:%.*]] = load i32, i32* [[GEP_3]], align 4
+; CHECK-NEXT:    [[R:%.*]] = add i32 [[L_4]], [[L_5]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+entry:
+  %l.0 = load i32, i32* %ptr.1, align 4
+  br i1 %c, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  ret i32 10
+
+if.end:                                           ; preds = %entry
+  %l.0.ext = zext i32 %l.0 to i64
+  %c.2 = icmp eq i64 %l.0.ext, 10
+  br i1 %c.2, label %if.2.end, label %if.2.then
+
+if.2.then:                                         ; preds = %if.end
+  %gep.1 = getelementptr inbounds i32, i32* %ptr.1, i64 %v
+  %l.2 = load i32, i32* %gep.1, align 4
+  br label %if.2.end
+
+if.2.end:                                         ; preds = %if.then7, %if.end
+  %rep.0 = phi i32 [ %l.2, %if.2.then ], [ %l.0, %if.end ]
+  %l.3 = load i32*, i32** %ptr.2, align 8
+  %rep.0.ext = zext i32 %rep.0 to i64
+  %gep.2 = getelementptr inbounds i32, i32* %ptr.1, i64 %rep.0.ext
+  %l.4 = load i32, i32* %gep.2, align 4
+  %gep.3 = getelementptr inbounds i32, i32* %l.3, i64 10
+  %l.5 = load i32, i32* %gep.3, align 4
+  %r = add i32 %l.4, %l.5
+  ret i32 %r
+}

diff  --git a/llvm/test/Transforms/GVN/PRE/pre-gep-load.ll b/llvm/test/Transforms/GVN/PRE/pre-gep-load.ll
index cfea28eff03c..33f145b70703 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-gep-load.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-gep-load.ll
@@ -38,7 +38,7 @@ define double @foo(i32 %stat, i32 %i, double** %p) {
 ; CHECK-NEXT:    [[TMP3:%.*]] = phi double* [ [[DOTPRE]], [[ENTRY_SW_BB2_CRIT_EDGE]] ], [ [[TMP0]], [[IF_END]] ]
 ; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds double, double* [[TMP3]], i64 [[IDXPROM3_PRE_PHI]]
 ; CHECK-NEXT:    [[SUB6:%.*]] = fsub double 3.000000e+00, [[TMP2]]
-; CHECK-NEXT:    store double [[SUB6]], double* [[ARRAYIDX5]]
+; CHECK-NEXT:    store double [[SUB6]], double* [[ARRAYIDX5]], align 8
 ; CHECK-NEXT:    br label [[RETURN]]
 ; CHECK:       sw.default:
 ; CHECK-NEXT:    br label [[RETURN]]
@@ -93,18 +93,15 @@ return:                                           ; preds = %sw.default, %sw.bb2
 
 define void @test_shortcut_safe(i1 %tst, i32 %p1, i32* %a) {
 ; CHECK-LABEL: @test_shortcut_safe(
-; CHECK-NEXT:    br i1 [[TST:%.*]], label [[SEXT1:%.*]], label [[DOTPRE_DEST_CRIT_EDGE:%.*]]
-; CHECK:       .pre.dest_crit_edge:
-; CHECK-NEXT:    [[DOTPRE1:%.*]] = sext i32 [[P1:%.*]] to i64
-; CHECK-NEXT:    br label [[PRE_DEST:%.*]]
+; CHECK-NEXT:    br i1 [[TST:%.*]], label [[SEXT1:%.*]], label [[PRE_DEST:%.*]]
 ; CHECK:       pre.dest:
-; CHECK-NEXT:    [[DOTPRE_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE1]], [[DOTPRE_DEST_CRIT_EDGE]] ], [ [[IDXPROM2_PRE_PHI:%.*]], [[SEXT_USE:%.*]] ]
-; CHECK-NEXT:    br label [[SEXT_USE]]
+; CHECK-NEXT:    [[DOTPRE:%.*]] = sext i32 [[P1:%.*]] to i64
+; CHECK-NEXT:    br label [[SEXT_USE:%.*]]
 ; CHECK:       sext1:
 ; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[P1]] to i64
 ; CHECK-NEXT:    br label [[SEXT_USE]]
 ; CHECK:       sext.use:
-; CHECK-NEXT:    [[IDXPROM2_PRE_PHI]] = phi i64 [ [[IDXPROM]], [[SEXT1]] ], [ [[DOTPRE_PRE_PHI]], [[PRE_DEST]] ]
+; CHECK-NEXT:    [[IDXPROM2_PRE_PHI:%.*]] = phi i64 [ [[IDXPROM]], [[SEXT1]] ], [ [[DOTPRE]], [[PRE_DEST]] ]
 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[IDXPROM2_PRE_PHI]]
 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4
 ; CHECK-NEXT:    tail call void @g(i32 [[VAL]])


        


More information about the llvm-branch-commits mailing list