
Fixes https://github.com/llvm/llvm-project/issues/59023 PHI nodes that are in the second loop only have the first loop as its predecessor. These PHI nodes should be sunk to the end of the fused loop. If the second loop uses the PHI, then the loops cannot be fused. I don't think this should happen in typical compilation workflows. The PHI will be in a dedicated exit block of the first loop following LCSSA transformations. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D139812
80 lines
2.8 KiB
LLVM
80 lines
2.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes=loop-fusion < %s 2>&1 | FileCheck %s
|
|
|
|
; Tests when the second loop preheader has a phi coming from the first loop
|
|
; exit. If the phi is not used in the second loop, the loops can be fused and
|
|
; the phi is sunk to the fused loop exit. If the phi is used in the second loop,
|
|
; the loops cannot be fused.
|
|
|
|
define void @test1() {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[VECTOR_PH:%.*]]
|
|
; CHECK: vector.ph:
|
|
; CHECK-NEXT: br label [[MIDDLE_BLOCK:%.*]]
|
|
; CHECK: middle.block:
|
|
; CHECK-NEXT: br i1 true, label [[FOR_END41:%.*]], label [[VECTOR_PH]]
|
|
; CHECK: for.end41:
|
|
; CHECK-NEXT: [[DOTLCSSA92:%.*]] = phi i16 [ 1, [[MIDDLE_BLOCK]] ]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %vector.ph
|
|
|
|
vector.ph: ; preds = %middle.block, %entry
|
|
br label %middle.block
|
|
|
|
middle.block: ; preds = %vector.ph
|
|
br i1 true, label %for.cond17.preheader, label %vector.ph
|
|
|
|
for.cond17.preheader: ; preds = %middle.block
|
|
%.lcssa92 = phi i16 [ 1, %middle.block ]
|
|
br label %vector.ph61
|
|
|
|
vector.ph61: ; preds = %middle.block59, %for.cond17.preheader
|
|
br i1 true, label %for.end41, label %vector.ph61
|
|
|
|
for.end41: ; preds = %middle.block59
|
|
ret void
|
|
}
|
|
|
|
define void @test2() {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[VECTOR_PH:%.*]]
|
|
; CHECK: vector.ph:
|
|
; CHECK-NEXT: br label [[MIDDLE_BLOCK:%.*]]
|
|
; CHECK: middle.block:
|
|
; CHECK-NEXT: br i1 true, label [[FOR_COND17_PREHEADER:%.*]], label [[VECTOR_PH]]
|
|
; CHECK: for.cond17.preheader:
|
|
; CHECK-NEXT: [[DOTLCSSA92:%.*]] = phi i16 [ 1, [[MIDDLE_BLOCK]] ]
|
|
; CHECK-NEXT: br label [[VECTOR_PH61:%.*]]
|
|
; CHECK: vector.ph61:
|
|
; CHECK-NEXT: call void @a(i16 [[DOTLCSSA92]])
|
|
; CHECK-NEXT: br i1 true, label [[FOR_END41:%.*]], label [[VECTOR_PH61]]
|
|
; CHECK: for.end41:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %vector.ph
|
|
|
|
vector.ph: ; preds = %middle.block, %entry
|
|
br label %middle.block
|
|
|
|
middle.block: ; preds = %vector.ph
|
|
br i1 true, label %for.cond17.preheader, label %vector.ph
|
|
|
|
for.cond17.preheader: ; preds = %middle.block
|
|
%.lcssa92 = phi i16 [ 1, %middle.block ]
|
|
br label %vector.ph61
|
|
|
|
vector.ph61: ; preds = %middle.block59, %for.cond17.preheader
|
|
call void @a(i16 %.lcssa92)
|
|
br i1 true, label %for.end41, label %vector.ph61
|
|
|
|
for.end41: ; preds = %middle.block59
|
|
ret void
|
|
}
|
|
|
|
declare void @a(i16);
|