Skip to content

Commit

Permalink
[GuardUtils] Revert llvm::isWidenableBranch change (#66411)
Browse files Browse the repository at this point in the history
In the d6e7c16 was introduced util to
to extract widenable conditions from branch. That util was applied in
the llvm::isWidenableBranch to check if branch is widenable. So we
consider branch is widenable if it has widenable condition anywhere in
the condition tree. But that will be true when we finish GuardWidening
reworking from branch widening to widenable conditions widening.
For now we still need to check that widenable branch is in the form of:
`br(widenable_condition & (...))`,
because that form is assumed by LoopPredication and GuardWidening
algorithms.

Fixes: #66418

Co-authored-by: Aleksander Popov <apopov@azul.com>
  • Loading branch information
aleks-tmb and Aleksander Popov committed Sep 20, 2023
1 parent 4670777 commit e9dfe08
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
5 changes: 4 additions & 1 deletion llvm/lib/Analysis/GuardUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ bool llvm::isWidenableCondition(const Value *V) {
}

bool llvm::isWidenableBranch(const User *U) {
return extractWidenableCondition(U) != nullptr;
Value *Condition, *WidenableCondition;
BasicBlock *GuardedBB, *DeoptBB;
return parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
DeoptBB);
}

bool llvm::isGuardAsWidenableBranch(const User *U) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,56 @@ exit: ; preds = %guarded, %entry
ret i32 %result
}

; TODO: Support widenable branch in the form of br((wc and cond0) and cond1)
; At present LoopPredication assumes the form of br(wc && (...)) only.
define i32 @wc_deep_in_expression_tree(i1 %cond0, i1 %cond1, i32 %limit) {
; CHECK-LABEL: @wc_deep_in_expression_tree(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[AND0:%.*]] = and i1 [[WC]], [[COND0:%.*]]
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[AND0]], [[COND1:%.*]]
; CHECK-NEXT: br i1 [[AND1]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp sgt i32 [[IV]], 100
; CHECK-NEXT: br i1 [[GUARD_COND]], label [[DEOPT_LOOPEXIT:%.*]], label [[GUARDED]]
; CHECK: guarded:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ult i32 [[IV]], [[LIMIT:%.*]]
; CHECK-NEXT: br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: deopt.loopexit:
; CHECK-NEXT: br label [[DEOPT]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
; CHECK: exit:
; CHECK-NEXT: ret i32 0
;
entry:
%wc = call i1 @llvm.experimental.widenable.condition()
%and0 = and i1 %wc, %cond0
%and1 = and i1 %and0, %cond1
br i1 %and1, label %loop, label %deopt

loop:
%iv = phi i32 [ %iv.next, %guarded ], [ 0, %entry ]
%guard.cond = icmp sgt i32 %iv, 100
br i1 %guard.cond, label %deopt, label %guarded

guarded:
%iv.next = add i32 %iv, 1
%exit.cond = icmp ult i32 %iv, %limit
br i1 %exit.cond, label %loop, label %exit

deopt:
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
ret i32 %deoptcall
exit:
ret i32 0
}

declare i32 @llvm.experimental.deoptimize.i32(...)

; Function Attrs: inaccessiblememonly nounwind
Expand Down

0 comments on commit e9dfe08

Please sign in to comment.