Skip to content

Commit

Permalink
Lower widenable_conditions in CGP
Browse files Browse the repository at this point in the history
This ensures that if we make it to the backend w/o lowering widenable_conditions first, that we generate correct code. Doing it in CGP - instead of isel - let's us fold control flow before hitting block local instruction selection.

Differential Revision: https://reviews.llvm.org/D57473

llvm-svn: 352779
  • Loading branch information
preames committed Jan 31, 2019
1 parent 02a86e6 commit ede49dd
Showing 2 changed files with 107 additions and 0 deletions.
14 changes: 14 additions & 0 deletions llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
@@ -1703,6 +1703,20 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
if (II) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::experimental_widenable_condition: {
// Give up on future widening oppurtunties so that we can fold away dead
// paths and merge blocks before going into block-local instruction
// selection.
if (II->use_empty()) {
II->eraseFromParent();
return true;
}
Constant *RetVal = ConstantInt::getTrue(II->getContext());
resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr);
});
return true;
}
case Intrinsic::objectsize: {
// Lower all uses of llvm.objectsize.*
Value *RetVal =
93 changes: 93 additions & 0 deletions llvm/test/Transforms/CodeGenPrepare/widenable-condition.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -codegenprepare -S < %s | FileCheck %s

; Check the idiomatic guard pattern to ensure it's lowered correctly.
define void @test_guard(i1 %cond_0) {
; CHECK-LABEL: @test_guard(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[COND_0:%.*]], label [[GUARDED:%.*]], label [[DEOPT:%.*]]
; CHECK: deopt:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: ret void
; CHECK: guarded:
; CHECK-NEXT: ret void
;
entry:
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
%exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
br i1 %exiplicit_guard_cond, label %guarded, label %deopt

deopt: ; preds = %entry
call void @foo()
ret void

guarded:
ret void
}

;; Test a non-guard fastpath/slowpath case
define void @test_triangle(i1 %cond_0) {
; CHECK-LABEL: @test_triangle(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[COND_0:%.*]], label [[FASTPATH:%.*]], label [[SLOWPATH:%.*]]
; CHECK: fastpath:
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: slowpath:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: ret void
;
entry:
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
%exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
br i1 %exiplicit_guard_cond, label %fastpath, label %slowpath

fastpath:
call void @bar()
br label %merge

slowpath:
call void @foo()
br label %merge

merge:
ret void
}


; Demonstrate that resulting CFG simplifications are made
define void @test_cfg_simplify() {
; CHECK-LABEL: @test_cfg_simplify(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret void
;
entry:
%widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
br i1 %widenable_cond3, label %guarded2, label %deopt3

deopt3:
call void @foo()
ret void

guarded2:
%widenable_cond4 = call i1 @llvm.experimental.widenable.condition()
br i1 %widenable_cond4, label %merge1, label %slowpath1

slowpath1:
call void @foo()
br label %merge1

merge1:
ret void
}


declare void @foo()
declare void @bar()

; Function Attrs: inaccessiblememonly nounwind
declare i1 @llvm.experimental.widenable.condition() #0

attributes #0 = { inaccessiblememonly nounwind }

0 comments on commit ede49dd

Please sign in to comment.