Skip to content

Commit

Permalink
LoopLoadElim: don't version single-iteration loops
Browse files Browse the repository at this point in the history
It is unnecessary for LoopLoadElim to version single-iteration loops.
Don't call LoopVersioning when the BTC is known to be 1.

Fixes llvm#96656.
  • Loading branch information
artagnon committed Jul 3, 2024
1 parent 93c9e03 commit 604c223
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 38 deletions.
9 changes: 5 additions & 4 deletions llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,10 +598,11 @@ class LoadEliminationForLoop {
}

// Point of no-return, start the transformation. First, version the loop
// if necessary.

LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
LV.versionLoop();
// if it's not a single-iteration loop.
if (!PSE.getBackedgeTakenCount()->isOne()) {
LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
LV.versionLoop();
}

// After versioning, some of the candidates' pointers could stop being
// SCEVAddRecs. We need to filter them out.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ define void @test(ptr %arg, i64 %arg1) {
; CHECK-NEXT: br label [[INNER_1_LVER_CHECK:%.*]]
; CHECK: inner.1.lver.check:
; CHECK-NEXT: [[PTR_PHI:%.*]] = phi ptr [ [[ARG:%.*]], [[BB:%.*]] ], [ @glob.1, [[OUTER_LATCH:%.*]] ]
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr double, ptr [[PTR_PHI]], i64 3
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds double, ptr [[PTR_PHI]], i64 3
; CHECK-NEXT: [[IDENT_CHECK:%.*]] = icmp ne i64 [[ARG1:%.*]], 1
; CHECK-NEXT: br i1 [[IDENT_CHECK]], label [[INNER_1_PH_LVER_ORIG:%.*]], label [[INNER_1_PH:%.*]]
; CHECK: inner.1.ph.lver.orig:
Expand All @@ -28,7 +28,7 @@ define void @test(ptr %arg, i64 %arg1) {
; CHECK-NEXT: [[TMP29_LVER_ORIG:%.*]] = load double, ptr [[GEP_4_LVER_ORIG]], align 8
; CHECK-NEXT: [[PTR_IV_1_NEXT_LVER_ORIG]] = getelementptr inbounds double, ptr [[PTR_IV_1_LVER_ORIG]], i64 1
; CHECK-NEXT: [[IV_NEXT_LVER_ORIG]] = add nuw nsw i64 [[IV_1_LVER_ORIG]], 1
; CHECK-NEXT: [[C_1_LVER_ORIG:%.*]] = icmp eq i64 [[IV_1_LVER_ORIG]], 1
; CHECK-NEXT: [[C_1_LVER_ORIG:%.*]] = icmp eq i64 [[IV_1_LVER_ORIG]], 2
; CHECK-NEXT: br i1 [[C_1_LVER_ORIG]], label [[INNER_1_EXIT_LOOPEXIT:%.*]], label [[INNER_1_LVER_ORIG]]
; CHECK: inner.1.ph:
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[PTR_PHI]], i64 16
Expand All @@ -46,7 +46,7 @@ define void @test(ptr %arg, i64 %arg1) {
; CHECK-NEXT: [[TMP29:%.*]] = load double, ptr [[GEP_4]], align 8
; CHECK-NEXT: [[PTR_IV_1_NEXT]] = getelementptr inbounds double, ptr [[PTR_IV_1]], i64 1
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV_1]], 1
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[IV_1]], 1
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[IV_1]], 2
; CHECK-NEXT: br i1 [[C_1]], label [[INNER_1_EXIT_LOOPEXIT1:%.*]], label [[INNER_1]]
; CHECK: inner.1.exit.loopexit:
; CHECK-NEXT: [[LCSSA_PTR_IV_1_PH:%.*]] = phi ptr [ [[PTR_IV_1_LVER_ORIG]], [[INNER_1_LVER_ORIG]] ]
Expand All @@ -72,7 +72,8 @@ define void @test(ptr %arg, i64 %arg1) {
; CHECK-NEXT: [[TMP0:%.*]] = shl i64 [[INDVAR_LCSSA]], 3
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 24
; CHECK-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, ptr [[LCSSA_PTR_IV_1]], i64 [[TMP1]]
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[GEP_7]], [[GEP_1]]
; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[PTR_PHI]], i64 32
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[GEP_7]], [[SCEVGEP4]]
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[PTR_PHI]], [[SCEVGEP3]]
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[INNER_3_PH_LVER_ORIG:%.*]], label [[INNER_3_PH:%.*]]
Expand All @@ -86,25 +87,25 @@ define void @test(ptr %arg, i64 %arg1) {
; CHECK-NEXT: [[GEP_9_LVER_ORIG:%.*]] = getelementptr double, ptr [[PTR_PHI]], i64 [[IV_2_LVER_ORIG]]
; CHECK-NEXT: [[TMP18_LVER_ORIG:%.*]] = load double, ptr [[GEP_9_LVER_ORIG]], align 8
; CHECK-NEXT: [[IV_2_NEXT_LVER_ORIG]] = add nuw nsw i64 [[IV_2_LVER_ORIG]], 1
; CHECK-NEXT: [[C_2_LVER_ORIG:%.*]] = icmp eq i64 [[IV_2_LVER_ORIG]], 1
; CHECK-NEXT: [[C_2_LVER_ORIG:%.*]] = icmp eq i64 [[IV_2_LVER_ORIG]], 2
; CHECK-NEXT: br i1 [[C_2_LVER_ORIG]], label [[OUTER_LATCH_LOOPEXIT:%.*]], label [[INNER_3_LVER_ORIG]]
; CHECK: inner.3.ph:
; CHECK-NEXT: [[LOAD_INITIAL5:%.*]] = load double, ptr [[PTR_PHI]], align 8
; CHECK-NEXT: [[LOAD_INITIAL6:%.*]] = load double, ptr [[PTR_PHI]], align 8
; CHECK-NEXT: br label [[INNER_3:%.*]]
; CHECK: inner.3:
; CHECK-NEXT: [[STORE_FORWARDED6:%.*]] = phi double [ [[LOAD_INITIAL5]], [[INNER_3_PH]] ], [ 0.000000e+00, [[INNER_3]] ]
; CHECK-NEXT: [[STORE_FORWARDED7:%.*]] = phi double [ [[LOAD_INITIAL6]], [[INNER_3_PH]] ], [ 0.000000e+00, [[INNER_3]] ]
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ 0, [[INNER_3_PH]] ], [ [[IV_2_NEXT:%.*]], [[INNER_3]] ]
; CHECK-NEXT: [[GEP_8:%.*]] = getelementptr inbounds double, ptr [[GEP_6]], i64 [[IV_2]]
; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP_7]], align 8
; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP_8]], align 8
; CHECK-NEXT: [[GEP_9:%.*]] = getelementptr double, ptr [[PTR_PHI]], i64 [[IV_2]]
; CHECK-NEXT: [[TMP18:%.*]] = load double, ptr [[GEP_9]], align 8
; CHECK-NEXT: [[IV_2_NEXT]] = add nuw nsw i64 [[IV_2]], 1
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i64 [[IV_2]], 1
; CHECK-NEXT: br i1 [[C_2]], label [[OUTER_LATCH_LOOPEXIT4:%.*]], label [[INNER_3]]
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i64 [[IV_2]], 2
; CHECK-NEXT: br i1 [[C_2]], label [[OUTER_LATCH_LOOPEXIT5:%.*]], label [[INNER_3]]
; CHECK: outer.latch.loopexit:
; CHECK-NEXT: br label [[OUTER_LATCH]]
; CHECK: outer.latch.loopexit4:
; CHECK: outer.latch.loopexit5:
; CHECK-NEXT: br label [[OUTER_LATCH]]
; CHECK: outer.latch:
; CHECK-NEXT: br label [[INNER_1_LVER_CHECK]]
Expand All @@ -128,7 +129,7 @@ inner.1:
%tmp29 = load double, ptr %gep.4, align 8
%ptr.iv.1.next = getelementptr inbounds double, ptr %ptr.iv.1, i64 1
%iv.next = add nuw nsw i64 %iv.1, 1
%c.1 = icmp eq i64 %iv.1, 1
%c.1 = icmp eq i64 %iv.1, 2
br i1 %c.1, label %inner.1.exit, label %inner.1

inner.1.exit: ; preds = %bb22
Expand All @@ -155,7 +156,7 @@ inner.3: ; preds = %bb14, %bb10
%gep.9 = getelementptr double, ptr %ptr.phi, i64 %iv.2
%tmp18 = load double, ptr %gep.9, align 8
%iv.2.next = add nuw nsw i64 %iv.2, 1
%c.2 = icmp eq i64 %iv.2, 1
%c.2 = icmp eq i64 %iv.2, 2
br i1 %c.2, label %outer.latch, label %inner.3

outer.latch:
Expand Down
25 changes: 3 additions & 22 deletions llvm/test/Transforms/LoopLoadElim/pr96656.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,11 @@ define void @single_iteration_versioning(ptr %arg, ptr %arg1, i1 %arg2) {
; CHECK-SAME: ptr [[ARG:%.*]], ptr [[ARG1:%.*]], i1 [[ARG2:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[ARG]], align 4
; CHECK-NEXT: br i1 [[ARG2]], label %[[NOLOOP_EXIT:.*]], label %[[LOOP_LVER_CHECK:.*]]
; CHECK: [[LOOP_LVER_CHECK]]:
; CHECK-NEXT: br i1 [[ARG2]], label %[[NOLOOP_EXIT:.*]], label %[[LOOP_PH:.*]]
; CHECK: [[LOOP_PH]]:
; CHECK-NEXT: [[SEXT7:%.*]] = sext i32 [[LOAD]] to i64
; CHECK-NEXT: [[GEP8:%.*]] = getelementptr i8, ptr [[ARG1]], i64 8
; CHECK-NEXT: [[GEP9:%.*]] = getelementptr i8, ptr [[ARG1]], i64 16
; CHECK-NEXT: [[IDENT_CHECK:%.*]] = icmp ne i32 [[LOAD]], 1
; CHECK-NEXT: br i1 [[IDENT_CHECK]], label %[[LOOP_PH_LVER_ORIG:.*]], label %[[LOOP_PH:.*]]
; CHECK: [[LOOP_PH_LVER_ORIG]]:
; CHECK-NEXT: br label %[[LOOP_LVER_ORIG:.*]]
; CHECK: [[LOOP_LVER_ORIG]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 0, %[[LOOP_PH_LVER_ORIG]] ], [ [[ADD:%.*]], %[[LOOP_LVER_ORIG]] ]
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[PHI]], [[SEXT7]]
; CHECK-NEXT: [[GEP10:%.*]] = getelementptr double, ptr [[GEP8]], i64 [[MUL]]
; CHECK-NEXT: [[LOAD11:%.*]] = load double, ptr [[GEP10]], align 8
; CHECK-NEXT: [[GEP13_LVER_ORIG:%.*]] = getelementptr double, ptr [[GEP9]], i64 [[MUL]]
; CHECK-NEXT: store double [[LOAD11]], ptr [[GEP13_LVER_ORIG]], align 8
; CHECK-NEXT: [[ADD]] = add i64 [[PHI]], 1
; CHECK-NEXT: [[ICMP_LVER_ORIG:%.*]] = icmp eq i64 [[PHI]], 1
; CHECK-NEXT: br i1 [[ICMP_LVER_ORIG]], label %[[EXIT_LOOPEXIT_LOOPEXIT:.*]], label %[[LOOP_LVER_ORIG]]
; CHECK: [[LOOP_PH]]:
; CHECK-NEXT: [[LOAD_INITIAL:%.*]] = load double, ptr [[GEP8]], align 8
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
Expand All @@ -38,17 +23,13 @@ define void @single_iteration_versioning(ptr %arg, ptr %arg1, i1 %arg2) {
; CHECK-NEXT: store double [[STORE_FORWARDED]], ptr [[GEP13]], align 8
; CHECK-NEXT: [[ADD1]] = add i64 [[PHI1]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[PHI1]], 1
; CHECK-NEXT: br i1 [[ICMP]], label %[[EXIT_LOOPEXIT_LOOPEXIT1:.*]], label %[[LOOP]]
; CHECK-NEXT: br i1 [[ICMP]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP]]
; CHECK: [[NOLOOP_EXIT]]:
; CHECK-NEXT: [[SEXT2:%.*]] = sext i32 [[LOAD]] to i64
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr double, ptr [[ARG1]], i64 [[SEXT2]]
; CHECK-NEXT: [[LOAD6:%.*]] = load double, ptr [[GEP2]], align 8
; CHECK-NEXT: store double [[LOAD6]], ptr [[ARG]], align 8
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[EXIT_LOOPEXIT_LOOPEXIT]]:
; CHECK-NEXT: br label %[[EXIT_LOOPEXIT:.*]]
; CHECK: [[EXIT_LOOPEXIT_LOOPEXIT1]]:
; CHECK-NEXT: br label %[[EXIT_LOOPEXIT]]
; CHECK: [[EXIT_LOOPEXIT]]:
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
Expand Down

0 comments on commit 604c223

Please sign in to comment.