mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
0516a9ad17
Summary: This is a revised version of D13974, and the following quoted summary are from D13974 "This patch adds support to check if a loop has loop invariant conditions which lead to loop exits. If so, we know that if the exit path is taken, it is at the first loop iteration. If there is an induction variable used in that exit path whose value has not been updated, it will keep its initial value passing from loop preheader. We can therefore rewrite the exit value with its initial value. This will help remove phis created by LCSSA and enable other optimizations like loop unswitch." D13974 was committed but failed one lnt test. The bug was that we only checked the condition from loop exit's incoming block was a loop invariant. But there could be another condition from loop header to that incoming block not being a loop invariant. This would produce miscompiled code. This patch fixes the issue by checking if the incoming block is loop header, and if not, don't perform the rewrite. The could be further improved by recursively checking all conditions leading to loop exit block, but I'd like to check in this simple version first and improve it with future patches. Reviewers: sanjoy Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D16570 llvm-svn: 258912
64 lines
1.4 KiB
LLVM
64 lines
1.4 KiB
LLVM
; RUN: opt -indvars -instcombine -S < %s | FileCheck %s
|
|
|
|
;; Test that loop's exit value is rewritten to its initial
|
|
;; value from loop preheader
|
|
define i32 @test1(i32* %var) {
|
|
; CHECK-LABEL: @test1
|
|
entry:
|
|
%cond = icmp eq i32* %var, null
|
|
br label %header
|
|
|
|
header:
|
|
%phi_indvar = phi i32 [0, %entry], [%indvar, %loop]
|
|
br i1 %cond, label %loop, label %exit
|
|
|
|
loop:
|
|
%indvar = add i32 %phi_indvar, 1
|
|
br label %header
|
|
|
|
exit:
|
|
; CHECK: ret i32 0
|
|
ret i32 %phi_indvar
|
|
}
|
|
|
|
;; Test that we can not rewrite loop exit value if it's not
|
|
;; a phi node (%indvar is an add instruction in this test).
|
|
define i32 @test2(i32* %var) {
|
|
; CHECK-LABEL: @test2
|
|
entry:
|
|
%cond = icmp eq i32* %var, null
|
|
br label %header
|
|
|
|
header:
|
|
%phi_indvar = phi i32 [0, %entry], [%indvar, %header]
|
|
%indvar = add i32 %phi_indvar, 1
|
|
br i1 %cond, label %header, label %exit
|
|
|
|
exit:
|
|
; CHECK: ret i32 %indvar
|
|
ret i32 %indvar
|
|
}
|
|
|
|
;; Test that we can not rewrite loop exit value if the condition
|
|
;; is not in loop header.
|
|
define i32 @test3(i32* %var) {
|
|
; CHECK-LABEL: @test3
|
|
entry:
|
|
%cond1 = icmp eq i32* %var, null
|
|
br label %header
|
|
|
|
header:
|
|
%phi_indvar = phi i32 [0, %entry], [%indvar, %header], [%indvar, %body]
|
|
%indvar = add i32 %phi_indvar, 1
|
|
%cond2 = icmp eq i32 %indvar, 10
|
|
br i1 %cond2, label %header, label %body
|
|
|
|
body:
|
|
br i1 %cond1, label %header, label %exit
|
|
|
|
exit:
|
|
; CHECK: ret i32 %phi_indvar
|
|
ret i32 %phi_indvar
|
|
}
|
|
|