mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-12 22:30:12 +00:00
![Sanjoy Das](/assets/img/avatar_default.png)
The bug was a result of getPreStartForExtend interpreting nsw/nuw flags on an add recurrence more strongly than is legal. {S,+,X}<nsw> implies S+X is nsw only if the backedge of the loop is taken at least once. NOTE: I had accidentally committed an unrelated change with the commit message of this change in r230275 (r230275 was reverted in r230279). This is the correct change for this commit message. Differential Revision: http://reviews.llvm.org/D7808 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230291 91177308-0d34-0410-b5e6-96231b3b80d8
83 lines
2.3 KiB
LLVM
83 lines
2.3 KiB
LLVM
; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
|
|
|
|
; An example run where SCEV(%postinc)->getStart() may overflow:
|
|
;
|
|
; %start = INT_SMAX
|
|
; %low.limit = INT_SMIN
|
|
; %high.limit = < not used >
|
|
;
|
|
; >> entry:
|
|
; %postinc.start = INT_SMIN
|
|
;
|
|
; >> loop:
|
|
; %idx = %start
|
|
; %postinc = INT_SMIN
|
|
; %postinc.inc = INT_SMIN + 1
|
|
; %postinc.sext = sext(INT_SMIN) = i64 INT32_SMIN
|
|
; %break.early = INT_SMIN `slt` INT_SMIN = false
|
|
; br i1 false, ___, %early.exit
|
|
;
|
|
; >> early.exit:
|
|
; ret i64 INT32_SMIN
|
|
|
|
|
|
define i64 @bad.0(i32 %start, i32 %low.limit, i32 %high.limit) {
|
|
; CHECK-LABEL: Classifying expressions for: @bad.0
|
|
entry:
|
|
%postinc.start = add i32 %start, 1
|
|
br label %loop
|
|
|
|
loop:
|
|
%idx = phi i32 [ %start, %entry ], [ %idx.inc, %continue ]
|
|
%postinc = phi i32 [ %postinc.start, %entry ], [ %postinc.inc, %continue ]
|
|
%postinc.inc = add nsw i32 %postinc, 1
|
|
%postinc.sext = sext i32 %postinc to i64
|
|
; CHECK: %postinc.sext = sext i32 %postinc to i64
|
|
; CHECK-NEXT: --> {(sext i32 (1 + %start) to i64),+,1}<nsw><%loop>
|
|
%break.early = icmp slt i32 %postinc, %low.limit
|
|
br i1 %break.early, label %continue, label %early.exit
|
|
|
|
continue:
|
|
%idx.inc = add nsw i32 %idx, 1
|
|
%cmp = icmp slt i32 %idx.inc, %high.limit
|
|
br i1 %cmp, label %loop, label %exit
|
|
|
|
exit:
|
|
ret i64 0
|
|
|
|
early.exit:
|
|
ret i64 %postinc.sext
|
|
}
|
|
|
|
define i64 @bad.1(i32 %start, i32 %low.limit, i32 %high.limit, i1* %unknown) {
|
|
; CHECK-LABEL: Classifying expressions for: @bad.1
|
|
entry:
|
|
%postinc.start = add i32 %start, 1
|
|
br label %loop
|
|
|
|
loop:
|
|
%idx = phi i32 [ %start, %entry ], [ %idx.inc, %continue ], [ %idx.inc, %continue.1 ]
|
|
%postinc = phi i32 [ %postinc.start, %entry ], [ %postinc.inc, %continue ], [ %postinc.inc, %continue.1 ]
|
|
%postinc.inc = add nsw i32 %postinc, 1
|
|
%postinc.sext = sext i32 %postinc to i64
|
|
; CHECK: %postinc.sext = sext i32 %postinc to i64
|
|
; CHECK-NEXT: --> {(sext i32 (1 + %start) to i64),+,1}<nsw><%loop>
|
|
%break.early = icmp slt i32 %postinc, %low.limit
|
|
br i1 %break.early, label %continue.1, label %early.exit
|
|
|
|
continue.1:
|
|
%cond = load volatile i1* %unknown
|
|
%idx.inc = add nsw i32 %idx, 1
|
|
br i1 %cond, label %loop, label %continue
|
|
|
|
continue:
|
|
%cmp = icmp slt i32 %idx.inc, %high.limit
|
|
br i1 %cmp, label %loop, label %exit
|
|
|
|
exit:
|
|
ret i64 0
|
|
|
|
early.exit:
|
|
ret i64 %postinc.sext
|
|
}
|