[llvm] 1f37088 - [Pipelines] Perform hoisting prior to GVN

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 7 01:06:09 PDT 2023


Author: Nikita Popov
Date: 2023-08-07T10:06:00+02:00
New Revision: 1f37088679a5c2416707d477093950e48148d430

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

LOG: [Pipelines] Perform hoisting prior to GVN

We currently only enable hoisting in the last SimplifyCFG run of
the function simplification pipeline. In particular this happens
after GVN, which means that instructions that were identical (and
thus hoistable) prior to GVN might no longer be so after it ran,
due to equality replacements (see the phase ordering test).

The history here is that D84108 restricted hoisting to the very
late (module optimization) pipeline only. Then D101468 went back
on that, and also performed it at the end of function simplification.
This patch goes one step further and allows it prior to GVN.
Importantly, we still don't perform hoisting before LoopRotate,
which was the original motivation for delaying it.

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

Added: 
    

Modified: 
    llvm/lib/Passes/PassBuilderPipelines.cpp
    llvm/test/Transforms/PhaseOrdering/gvn-replacement-vs-hoist.ll
    llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 660cb2e974d781..a13b5d125d6d61 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -640,8 +640,9 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
   FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM1),
                                               /*UseMemorySSA=*/true,
                                               /*UseBlockFrequencyInfo=*/true));
-  FPM.addPass(
-      SimplifyCFGPass(SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
+  FPM.addPass(SimplifyCFGPass(
+      SimplifyCFGOptions().hoistCommonInsts(true).convertSwitchRangeToICmp(
+          true)));
   FPM.addPass(InstCombinePass());
   // The loop passes in LPM2 (LoopIdiomRecognizePass, IndVarSimplifyPass,
   // LoopDeletionPass and LoopFullUnrollPass) do not preserve MemorySSA.

diff  --git a/llvm/test/Transforms/PhaseOrdering/gvn-replacement-vs-hoist.ll b/llvm/test/Transforms/PhaseOrdering/gvn-replacement-vs-hoist.ll
index ea863f7355ad9f..ce67b4f72f09fe 100644
--- a/llvm/test/Transforms/PhaseOrdering/gvn-replacement-vs-hoist.ll
+++ b/llvm/test/Transforms/PhaseOrdering/gvn-replacement-vs-hoist.ll
@@ -5,26 +5,17 @@ define void @test(ptr noundef %a, i32 noundef %beam) {
 ; CHECK-LABEL: define void @test
 ; CHECK-SAME: (ptr nocapture noundef writeonly [[A:%.*]], i32 noundef [[BEAM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[MUL:%.*]] = shl nuw nsw i32 [[BEAM]], 1
-; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MUL]] to i64
-; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM]]
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.cond.cleanup:
 ; CHECK-NEXT:    ret void
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I_06]], [[BEAM]]
-; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4
-; CHECK-NEXT:    br label [[FOR_INC]]
-; CHECK:       if.else:
-; CHECK-NEXT:    [[MUL2:%.*]] = shl nuw nsw i32 [[I_06]], 1
-; CHECK-NEXT:    [[IDXPROM3:%.*]] = zext i32 [[MUL2]] to i64
-; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM3]]
-; CHECK-NEXT:    store i32 1, ptr [[ARRAYIDX4]], align 4
-; CHECK-NEXT:    br label [[FOR_INC]]
-; CHECK:       for.inc:
+; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[I_06]], [[BEAM]]
+; CHECK-NEXT:    [[MUL:%.*]] = shl nuw nsw i32 [[I_06]], 1
+; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[MUL]] to i64
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[CMP1]] to i32
+; CHECK-NEXT:    store i32 [[SPEC_SELECT]], ptr [[ARRAYIDX]], align 4
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[I_06]], 9999
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]

diff  --git a/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll b/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll
index b5bba73e05f836..f8414c96b7c94f 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll
@@ -51,8 +51,8 @@ define void @_Z4loopi(i32 %width) {
 ; HOIST-NEXT:    br label [[FOR_COND:%.*]]
 ; HOIST:       for.cond:
 ; HOIST-NEXT:    [[I_0:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[FOR_COND_PREHEADER]] ]
-; HOIST-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[I_0]], [[SUB]]
 ; HOIST-NEXT:    tail call void @f0()
+; HOIST-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[I_0]], [[SUB]]
 ; HOIST-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
 ; HOIST:       for.cond.cleanup:
 ; HOIST-NEXT:    tail call void @f2()


        


More information about the llvm-commits mailing list