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]]) _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits