mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
ba797dbf52
The motivating case is an otherwise dead loop with a fence in it. At the moment, this goes all the way through the optimizer and we end up emitting an entirely pointless loop on x86. This case may seem a bit contrived, but we've seen it in real code as the result of otherwise reasonable lowering strategies combined w/thread local memory optimizations (such as escape analysis). To handle this simple case, we can teach LICM to hoist must execute fences when there is no other memory operation within the loop. Differential Revision: https://reviews.llvm.org/D50489 llvm-svn: 339378
121 lines
2.4 KiB
LLVM
121 lines
2.4 KiB
LLVM
; RUN: opt -licm -basicaa < %s -S | FileCheck %s
|
|
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
|
|
|
|
define void @test1(i64 %n) {
|
|
; CHECK-LABEL: @test1
|
|
; CHECK: fence
|
|
; CHECK-LABEL: loop:
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence release
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test2(i64 %n) {
|
|
; CHECK-LABEL: @test2
|
|
; CHECK: fence
|
|
; CHECK-LABEL: loop:
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence acquire
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test3(i64 %n) {
|
|
; CHECK-LABEL: @test3
|
|
; CHECK: fence
|
|
; CHECK-LABEL: loop:
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence acq_rel
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @test4(i64 %n) {
|
|
; CHECK-LABEL: @test4
|
|
; CHECK: fence
|
|
; CHECK-LABEL: loop:
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence seq_cst
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @testneg1(i64 %n, i64* %p) {
|
|
; CHECK-LABEL: @testneg1
|
|
; CHECK-LABEL: loop:
|
|
; CHECK: fence
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
store i64 %iv, i64* %p
|
|
fence release
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @testneg2(i64* %p) {
|
|
; CHECK-LABEL: @testneg2
|
|
; CHECK-LABEL: loop:
|
|
; CHECK: fence
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence acquire
|
|
%n = load i64, i64* %p
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; Note: While a false negative for LICM on it's own, O3 does get this
|
|
; case by combining the fences.
|
|
define void @testfn1(i64 %n, i64* %p) {
|
|
; CHECK-LABEL: @testfn1
|
|
; CHECK-LABEL: loop:
|
|
; CHECK: fence
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %loop]
|
|
fence release
|
|
fence release
|
|
%iv.next = add i64 %iv, 1
|
|
%test = icmp slt i64 %iv, %n
|
|
br i1 %test, label %loop, label %exit
|
|
exit:
|
|
ret void
|
|
}
|
|
|