mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-06 12:26:45 +00:00
4db527032a
Summary: In RewriteLoopExitValues, before expanding out an SCEV expression using SCEVExpander, try to see if an existing LLVM IR expression already computes the value we're interested in. If so use that existing expression. Apart from reducing IndVars' reliance on the rest of the compilation pipeline, this also prevents IndVars from concluding some expressions as "high cost" when they're not. For instance, `InductiveRangeCheckElimination` often emits code of the following form: ``` len = umin(len_A, len_B) loop: ... if (i++ < len) goto loop outside_loop: use(i) ``` `SCEVExpander` refuses to rewrite the use of `i` in `outside_loop`, since it thinks the value of `i` on loop exit, `len`, is a high cost expansion since it contains an `umax` in it. With this change, `IndVars` can see that it can re-use `len` instead of creating a new expression to compute `umin(len_A, len_B)`. I considered putting this cleverness in `SCEVExpander`, but I was worried that it may then have a deterimental effect on other passes that use it. So I decided it was better to just do this in the one place where it seems like an obviously good idea, with the intent of generalizing later if needed. Reviewers: atrick, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10782 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241838 91177308-0d34-0410-b5e6-96231b3b80d8
37 lines
1.2 KiB
LLVM
37 lines
1.2 KiB
LLVM
; RUN: opt -S -indvars < %s | FileCheck %s
|
|
|
|
define void @f(i32 %length.i.88, i32 %length.i, i8* %tmp12, i32 %tmp10, i8* %tmp8) {
|
|
; CHECK-LABEL: @f(
|
|
not_zero11.preheader:
|
|
%tmp13 = icmp ugt i32 %length.i, %length.i.88
|
|
%tmp14 = select i1 %tmp13, i32 %length.i.88, i32 %length.i
|
|
%tmp15 = icmp sgt i32 %tmp14, 0
|
|
br i1 %tmp15, label %not_zero11, label %not_zero11.postloop
|
|
|
|
not_zero11:
|
|
%v_1 = phi i32 [ %tmp22, %not_zero11 ], [ 0, %not_zero11.preheader ]
|
|
%tmp16 = zext i32 %v_1 to i64
|
|
%tmp17 = getelementptr inbounds i8, i8* %tmp8, i64 %tmp16
|
|
%tmp18 = load i8, i8* %tmp17, align 1
|
|
%tmp19 = zext i8 %tmp18 to i32
|
|
%tmp20 = or i32 %tmp19, %tmp10
|
|
%tmp21 = trunc i32 %tmp20 to i8
|
|
%addr22 = getelementptr inbounds i8, i8* %tmp12, i64 %tmp16
|
|
store i8 %tmp21, i8* %addr22, align 1
|
|
%tmp22 = add nuw nsw i32 %v_1, 1
|
|
%tmp23 = icmp slt i32 %tmp22, %tmp14
|
|
br i1 %tmp23, label %not_zero11, label %main.exit.selector
|
|
|
|
main.exit.selector:
|
|
; CHECK-LABEL: main.exit.selector:
|
|
; CHECK: %tmp24 = icmp slt i32 %tmp14, %length.i
|
|
%tmp24 = icmp slt i32 %tmp22, %length.i
|
|
br i1 %tmp24, label %not_zero11.postloop, label %leave
|
|
|
|
leave:
|
|
ret void
|
|
|
|
not_zero11.postloop:
|
|
ret void
|
|
}
|