1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00
llvm-mirror/test/Transforms/LICM/promote-capture.ll
Nikita Popov 22ddf9b599 [LICM] Make capture check more precise
During store promotion, we check whether the pointer was captured
to exclude potential reads from other threads. However, we're only
interested in captures before or inside the loop. Check this using
PointerMayBeCapturedBefore against the loop header.

Differential Revision: https://reviews.llvm.org/D100706
2021-04-19 20:34:23 +02:00

156 lines
4.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes='loop-mssa(licm)' < %s | FileCheck %s
declare i1 @cond(i32 %v) readnone
declare void @capture(i32* %p) readnone
define void @test_captured_after_loop(i32 %len) {
; CHECK-LABEL: @test_captured_after_loop(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COUNT:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 0, i32* [[COUNT]], align 4
; CHECK-NEXT: [[COUNT_PROMOTED:%.*]] = load i32, i32* [[COUNT]], align 4
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[C_INC2:%.*]] = phi i32 [ [[COUNT_PROMOTED]], [[ENTRY:%.*]] ], [ [[C_INC1:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[LATCH]] ]
; CHECK-NEXT: [[COND:%.*]] = call i1 @cond(i32 [[I]])
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[LATCH]]
; CHECK: if:
; CHECK-NEXT: [[C_INC:%.*]] = add i32 [[C_INC2]], 1
; CHECK-NEXT: br label [[LATCH]]
; CHECK: latch:
; CHECK-NEXT: [[C_INC1]] = phi i32 [ [[C_INC]], [[IF]] ], [ [[C_INC2]], [[LOOP]] ]
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[LEN:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[C_INC1_LCSSA:%.*]] = phi i32 [ [[C_INC1]], [[LATCH]] ]
; CHECK-NEXT: store i32 [[C_INC1_LCSSA]], i32* [[COUNT]], align 4
; CHECK-NEXT: call void @capture(i32* [[COUNT]])
; CHECK-NEXT: ret void
;
entry:
%count = alloca i32
store i32 0, i32* %count
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
%cond = call i1 @cond(i32 %i)
br i1 %cond, label %if, label %latch
if:
%c = load i32, i32* %count
%c.inc = add i32 %c, 1
store i32 %c.inc, i32* %count
br label %latch
latch:
%i.next = add nuw i32 %i, 1
%cmp = icmp eq i32 %i.next, %len
br i1 %cmp, label %exit, label %loop
exit:
call void @capture(i32* %count)
ret void
}
define void @test_captured_in_loop(i32 %len) {
; CHECK-LABEL: @test_captured_in_loop(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COUNT:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 0, i32* [[COUNT]], align 4
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[COND:%.*]] = call i1 @cond(i32 [[I]])
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[LATCH]]
; CHECK: if:
; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[COUNT]], align 4
; CHECK-NEXT: [[C_INC:%.*]] = add i32 [[C]], 1
; CHECK-NEXT: store i32 [[C_INC]], i32* [[COUNT]], align 4
; CHECK-NEXT: call void @capture(i32* [[COUNT]])
; CHECK-NEXT: br label [[LATCH]]
; CHECK: latch:
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[LEN:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%count = alloca i32
store i32 0, i32* %count
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
%cond = call i1 @cond(i32 %i)
br i1 %cond, label %if, label %latch
if:
%c = load i32, i32* %count
%c.inc = add i32 %c, 1
store i32 %c.inc, i32* %count
call void @capture(i32* %count)
br label %latch
latch:
%i.next = add nuw i32 %i, 1
%cmp = icmp eq i32 %i.next, %len
br i1 %cmp, label %exit, label %loop
exit:
ret void
}
define void @test_captured_before_loop(i32 %len) {
; CHECK-LABEL: @test_captured_before_loop(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COUNT:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 0, i32* [[COUNT]], align 4
; CHECK-NEXT: call void @capture(i32* [[COUNT]])
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[COND:%.*]] = call i1 @cond(i32 [[I]])
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[LATCH]]
; CHECK: if:
; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[COUNT]], align 4
; CHECK-NEXT: [[C_INC:%.*]] = add i32 [[C]], 1
; CHECK-NEXT: store i32 [[C_INC]], i32* [[COUNT]], align 4
; CHECK-NEXT: br label [[LATCH]]
; CHECK: latch:
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[LEN:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%count = alloca i32
store i32 0, i32* %count
call void @capture(i32* %count)
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
%cond = call i1 @cond(i32 %i)
br i1 %cond, label %if, label %latch
if:
%c = load i32, i32* %count
%c.inc = add i32 %c, 1
store i32 %c.inc, i32* %count
br label %latch
latch:
%i.next = add nuw i32 %i, 1
%cmp = icmp eq i32 %i.next, %len
br i1 %cmp, label %exit, label %loop
exit:
ret void
}