mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
7b453f02d1
The idea of partial unswitching is to take a *part* of a branch's condition that is loop invariant and just unswitching that part. This primarily makes sense with i1 conditions of branches as opposed to switches. When dealing with i1 conditions, we can easily extract loop invariant inputs to a a branch and unswitch them to test them entirely outside the loop. As part of this, we now create much more significant cruft in the loop body, so this relies on adding cleanup passes to the loop pipeline and revisiting unswitched loops to do that cleanup before continuing to process them. This already appears to be more powerful at unswitching than the old loop unswitch pass, and so I'd appreciate pretty careful review in case I'm just missing some correctness checks. The `LIV-loop-condition` test case is not unswitched by the old unswitch pass, but is with this pass. Thanks to Sanjoy and Fedor for the review! Differential Revision: https://reviews.llvm.org/D46706 llvm-svn: 335156
37 lines
1.1 KiB
LLVM
37 lines
1.1 KiB
LLVM
; RUN: opt < %s -simple-loop-unswitch -S 2>&1 | FileCheck %s
|
|
|
|
; This is to test trivial loop unswitch only happens when trivial condition
|
|
; itself is an LIV loop condition (not partial LIV which could occur in and/or).
|
|
|
|
define i32 @test(i1 %cond1, i32 %var1) {
|
|
; CHECK-LABEL: define i32 @test(
|
|
entry:
|
|
br label %loop_begin
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split
|
|
;
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label %loop_begin
|
|
|
|
loop_begin:
|
|
%var3 = phi i32 [%var1, %entry], [%var2, %do_something]
|
|
%cond2 = icmp eq i32 %var3, 10
|
|
%cond.and = and i1 %cond1, %cond2
|
|
br i1 %cond.and, label %do_something, label %loop_exit
|
|
; CHECK: loop_begin:
|
|
; CHECK-NEXT: %[[VAR3:.*]] = phi i32
|
|
; CHECK-NEXT: %[[COND2:.*]] = icmp eq i32 %[[VAR3]], 10
|
|
; CHECK-NEXT: %[[COND_AND:.*]] = and i1 true, %[[COND2]]
|
|
; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
|
|
|
|
do_something:
|
|
%var2 = add i32 %var3, 1
|
|
call void @some_func() noreturn nounwind
|
|
br label %loop_begin
|
|
|
|
loop_exit:
|
|
ret i32 0
|
|
}
|
|
|
|
declare void @some_func() noreturn
|