Files
clang-p2996/llvm/test/Transforms/LoopFusion/sink_load.ll
Aaron Kogon ae05b9dc30 Sink/hoist memory instructions between loop fusion candidates
Currently, instructions in the preheader of the second of two fusion
candidates are sunk and hoisted whenever possible, to try to allow the
loops to fuse. Memory instructions are skipped, and are never sunk or
hoisted. This change adds memory instructions for sinking/hoisting
consideration.

This change uses DependenceAnalysis to check if a mem inst in the
preheader of FC1 depends on an instruction in FC0's header, across
which it will be hoisted, or FC1's header, across which it will be
sunk. We reject cases where the dependency is a data hazard.

Differential Revision: https://reviews.llvm.org/D131606
2022-09-07 07:42:00 -04:00

49 lines
1.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -loop-simplify -loop-fusion -debug-only=loop-fusion < %s 2>&1 | FileCheck %s
; REQUIRES: asserts
; CHECK: Safe to sink.
@A = common global [100 x i32] zeroinitializer, align 16
define void @sink_preheader(i32 %N) {
; CHECK-LABEL: @sink_preheader(
; CHECK-NEXT: pre1:
; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4
; CHECK-NEXT: br label [[BODY1:%.*]]
; CHECK: body1:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[BODY1]] ], [ 0, [[PRE1:%.*]] ]
; CHECK-NEXT: [[I2:%.*]] = phi i32 [ [[I_NEXT2:%.*]], [[BODY1]] ], [ 0, [[PRE1]] ]
; CHECK-NEXT: [[I_NEXT]] = add i32 1, [[I]]
; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], [[N:%.*]]
; CHECK-NEXT: store i32 3, i32* [[PTR]], align 4
; CHECK-NEXT: [[I_NEXT2]] = add i32 1, [[I2]]
; CHECK-NEXT: [[COND2:%.*]] = icmp ne i32 [[I2]], [[N]]
; CHECK-NEXT: br i1 [[COND2]], label [[BODY1]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[PTR]], align 4
; CHECK-NEXT: ret void
;
pre1:
%ptr = alloca i32
br label %body1
body1: ; preds = %pre1, %body1
%i = phi i32 [%i_next, %body1], [0, %pre1]
%i_next = add i32 1, %i
%cond = icmp ne i32 %i, %N
store i32 3, i32* %ptr
br i1 %cond, label %body1, label %pre2
pre2:
%b = load i32, i32 * %ptr
br label %body2
body2: ; preds = %pre2, %body2
%i2 = phi i32 [%i_next2, %body2], [0, %pre2]
%i_next2 = add i32 1, %i2
%cond2 = icmp ne i32 %i2, %N
br i1 %cond2, label %body2, label %exit
exit:
ret void
}