mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:50:30 +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)
|
||||
return false;
|
||||
|
||||
// If it is already predicated, check if its predicate subsumes the new
|
||||
// predicate.
|
||||
if (BBI.Predicate.size() && !TII->SubsumesPredicate(BBI.Predicate, Pred))
|
||||
// If it is already predicated, check if the new predicate subsumes
|
||||
// its predicate.
|
||||
if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))
|
||||
return false;
|
||||
|
||||
if (BBI.BrCond.size()) {
|
||||
|
@ -69,3 +69,62 @@ bb6.i350: ; preds = %bb2.i
|
||||
KBBlockZero.exit: ; preds = %bb2.i
|
||||
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