diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/CodeGenPrepare/widenable-condition.ll | 93 |
2 files changed, 107 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index e382798b692..7d5d8399731 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -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 = diff --git a/llvm/test/Transforms/CodeGenPrepare/widenable-condition.ll b/llvm/test/Transforms/CodeGenPrepare/widenable-condition.ll new file mode 100644 index 00000000000..a12b87ff115 --- /dev/null +++ b/llvm/test/Transforms/CodeGenPrepare/widenable-condition.ll @@ -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 } |

