mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
Fix a bug in IfConverter with nested predicates.
Prior to this patch, IfConverter may widen the cases where a sequence of instructions were executed because of the way it uses nested predicates. This result in incorrect execution. For instance, Let A be a basic block that flows conditionally into B and B be a predicated block. B can be predicated with A.BrToBPredicate into A iff B.Predicate is less "permissive" than A.BrToBPredicate, i.e., iff A.BrToBPredicate subsumes B.Predicate. The IfConverter was checking the opposite: B.Predicate subsumes A.BrToBPredicate. <rdar://problem/14379453> llvm-svn: 187071
This commit is contained in:
parent
bf520fe923
commit
83197eea3a
@ -720,9 +720,9 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
|
|||||||
if (BBI.IsDone || BBI.IsUnpredicable)
|
if (BBI.IsDone || BBI.IsUnpredicable)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If it is already predicated, check if its predicate subsumes the new
|
// If it is already predicated, check if the new predicate subsumes
|
||||||
// predicate.
|
// its predicate.
|
||||||
if (BBI.Predicate.size() && !TII->SubsumesPredicate(BBI.Predicate, Pred))
|
if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (BBI.BrCond.size()) {
|
if (BBI.BrCond.size()) {
|
||||||
|
@ -69,3 +69,62 @@ bb6.i350: ; preds = %bb2.i
|
|||||||
KBBlockZero.exit: ; preds = %bb2.i
|
KBBlockZero.exit: ; preds = %bb2.i
|
||||||
indirectbr i8* undef, [label %KBBlockZero_return_1, label %KBBlockZero_return_0]
|
indirectbr i8* undef, [label %KBBlockZero_return_1, label %KBBlockZero_return_0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; If-converter was checking for the wrong predicate subsumes pattern when doing
|
||||||
|
; nested predicates.
|
||||||
|
; E.g., Let A be a basic block that flows conditionally into B and B be a
|
||||||
|
; predicated block.
|
||||||
|
; B can be predicated with A.BrToBPredicate into A iff B.Predicate is less
|
||||||
|
; "permissive" than A.BrToBPredicate, i.e., iff A.BrToBPredicate subsumes
|
||||||
|
; B.Predicate.
|
||||||
|
; <rdar://problem/14379453>
|
||||||
|
|
||||||
|
; Hard-coded registers comes from the ABI.
|
||||||
|
; CHECK: wrapDistance:
|
||||||
|
; CHECK: cmp r1, #59
|
||||||
|
; CHECK-NEXT: itt le
|
||||||
|
; CHECK-NEXT: suble r0, r2, #1
|
||||||
|
; CHECK-NEXT: bxle lr
|
||||||
|
; CHECK-NEXT: subs [[REG:r[0-9]+]], #120
|
||||||
|
; CHECK-NEXT: cmp [[REG]], r1
|
||||||
|
; CHECK-NOT: it lt
|
||||||
|
; CHECK-NEXT: bge [[LABEL:.+]]
|
||||||
|
; Next BB
|
||||||
|
; CHECK-NOT: cmplt
|
||||||
|
; CHECK: cmp r0, #119
|
||||||
|
; CHECK-NEXT: itt le
|
||||||
|
; CHECK-NEXT: addle r0, r1, #1
|
||||||
|
; CHECK-NEXT: bxle lr
|
||||||
|
; Next BB
|
||||||
|
; CHECK: [[LABEL]]:
|
||||||
|
; CHECK-NEXT: subs r0, r1, r0
|
||||||
|
; CHECK-NEXT: bx lr
|
||||||
|
define i32 @wrapDistance(i32 %tx, i32 %sx, i32 %w) {
|
||||||
|
entry:
|
||||||
|
%cmp = icmp slt i32 %sx, 60
|
||||||
|
br i1 %cmp, label %if.then, label %if.else
|
||||||
|
|
||||||
|
if.then: ; preds = %entry
|
||||||
|
%sub = add nsw i32 %w, -1
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
if.else: ; preds = %entry
|
||||||
|
%sub1 = add nsw i32 %w, -120
|
||||||
|
%cmp2 = icmp slt i32 %sub1, %sx
|
||||||
|
%cmp3 = icmp slt i32 %tx, 120
|
||||||
|
%or.cond = and i1 %cmp2, %cmp3
|
||||||
|
br i1 %or.cond, label %if.then4, label %if.end5
|
||||||
|
|
||||||
|
if.then4: ; preds = %if.else
|
||||||
|
%add = add nsw i32 %sx, 1
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
if.end5: ; preds = %if.else
|
||||||
|
%sub6 = sub nsw i32 %sx, %tx
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %if.end5, %if.then4, %if.then
|
||||||
|
%retval.0 = phi i32 [ %sub, %if.then ], [ %add, %if.then4 ], [ %sub6, %if.end5 ]
|
||||||
|
ret i32 %retval.0
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user