From 3396a8da4a7eb6087934ed95f1585558dd12f08c Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Thu, 31 Jan 2019 18:45:46 +0000 Subject: [PATCH] Lower widenable_conditions in CGP 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352779 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenPrepare.cpp | 14 +++ .../CodeGenPrepare/widenable-condition.ll | 93 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 test/Transforms/CodeGenPrepare/widenable-condition.ll diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index e382798b692..7d5d8399731 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/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/test/Transforms/CodeGenPrepare/widenable-condition.ll b/test/Transforms/CodeGenPrepare/widenable-condition.ll new file mode 100644 index 00000000000..a12b87ff115 --- /dev/null +++ b/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 } -- 2.40.0