From: Max Kazantsev Date: Thu, 31 Jan 2019 09:10:17 +0000 (+0000) Subject: Default lowering for experimental.widenable.condition X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3dc9375185444d9709051d509f95e510a7e3b384;p=llvm Default lowering for experimental.widenable.condition Introduces a pass that provides default lowering strategy for the `experimental.widenable.condition` intrinsic, replacing all its uses with `i1 true`. Differential Revision: https://reviews.llvm.org/D56096 Reviewed By: reames git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352739 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 739c578f21e..fe6c17182a8 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -240,6 +240,7 @@ void initializeLowerAtomicLegacyPassPass(PassRegistry&); void initializeLowerEmuTLSPass(PassRegistry&); void initializeLowerExpectIntrinsicPass(PassRegistry&); void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&); +void initializeLowerWidenableConditionLegacyPassPass(PassRegistry&); void initializeLowerIntrinsicsPass(PassRegistry&); void initializeLowerInvokeLegacyPassPass(PassRegistry&); void initializeLowerSwitchPass(PassRegistry&); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 9f97ab755f3..97a4c06cdc9 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -357,6 +357,12 @@ Pass *createLowerAtomicPass(); // Pass *createLowerGuardIntrinsicPass(); +//===----------------------------------------------------------------------===// +// +// LowerWidenableCondition - Lower widenable condition to i1 true. +// +Pass *createLowerWidenableConditionPass(); + //===----------------------------------------------------------------------===// // // MergeICmps - Merge integer comparison chains into a memcmp diff --git a/include/llvm/Transforms/Scalar/LowerWidenableCondition.h b/include/llvm/Transforms/Scalar/LowerWidenableCondition.h new file mode 100644 index 00000000000..6dd786b2d34 --- /dev/null +++ b/include/llvm/Transforms/Scalar/LowerWidenableCondition.h @@ -0,0 +1,27 @@ +//===--- LowerWidenableCondition.h - Lower the guard intrinsic ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass lowers the llvm.widenable.condition intrinsic to default value +// which is i1 true. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H +#define LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +struct LowerWidenableConditionPass : PassInfoMixin { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +} + +#endif //LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 045c8541c0d..de9e67ba5d7 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -133,6 +133,7 @@ #include "llvm/Transforms/Scalar/LowerAtomic.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h" +#include "llvm/Transforms/Scalar/LowerWidenableCondition.h" #include "llvm/Transforms/Scalar/MakeGuardsExplicit.h" #include "llvm/Transforms/Scalar/MemCpyOptimizer.h" #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 972fce93426..3a4d6bd9f38 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -177,6 +177,7 @@ FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass()) FUNCTION_PASS("loweratomic", LowerAtomicPass()) FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) FUNCTION_PASS("lower-guard-intrinsic", LowerGuardIntrinsicPass()) +FUNCTION_PASS("lower-widenable-condition", LowerWidenableConditionPass()) FUNCTION_PASS("guard-widening", GuardWideningPass()) FUNCTION_PASS("gvn", GVN()) FUNCTION_PASS("load-store-vectorizer", LoadStoreVectorizerPass()) diff --git a/lib/Transforms/Scalar/CMakeLists.txt b/lib/Transforms/Scalar/CMakeLists.txt index e3548ce5cd0..9c33971ce0f 100644 --- a/lib/Transforms/Scalar/CMakeLists.txt +++ b/lib/Transforms/Scalar/CMakeLists.txt @@ -45,6 +45,7 @@ add_llvm_library(LLVMScalarOpts LowerAtomic.cpp LowerExpectIntrinsic.cpp LowerGuardIntrinsic.cpp + LowerWidenableCondition.cpp MakeGuardsExplicit.cpp MemCpyOptimizer.cpp MergeICmps.cpp diff --git a/lib/Transforms/Scalar/LowerWidenableCondition.cpp b/lib/Transforms/Scalar/LowerWidenableCondition.cpp new file mode 100644 index 00000000000..6a83d062b71 --- /dev/null +++ b/lib/Transforms/Scalar/LowerWidenableCondition.cpp @@ -0,0 +1,86 @@ +//===- LowerWidenableCondition.cpp - Lower the guard intrinsic ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass lowers the llvm.widenable.condition intrinsic to default value +// which is i1 true. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar/LowerWidenableCondition.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/GuardUtils.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PatternMatch.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/GuardUtils.h" + +using namespace llvm; + +namespace { +struct LowerWidenableConditionLegacyPass : public FunctionPass { + static char ID; + LowerWidenableConditionLegacyPass() : FunctionPass(ID) { + initializeLowerWidenableConditionLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; +}; +} + +static bool lowerWidenableCondition(Function &F) { + // Check if we can cheaply rule out the possibility of not having any work to + // do. + auto *WCDecl = F.getParent()->getFunction( + Intrinsic::getName(Intrinsic::experimental_widenable_condition)); + if (!WCDecl || WCDecl->use_empty()) + return false; + + using namespace llvm::PatternMatch; + SmallVector ToLower; + for (auto &I : instructions(F)) + if (match(&I, m_Intrinsic())) + ToLower.push_back(cast(&I)); + + if (ToLower.empty()) + return false; + + for (auto *CI : ToLower) { + CI->replaceAllUsesWith(ConstantInt::getTrue(CI->getContext())); + CI->eraseFromParent(); + } + return true; +} + +bool LowerWidenableConditionLegacyPass::runOnFunction(Function &F) { + return lowerWidenableCondition(F); +} + +char LowerWidenableConditionLegacyPass::ID = 0; +INITIALIZE_PASS(LowerWidenableConditionLegacyPass, "lower-widenable-condition", + "Lower the widenable condition to default true value", false, + false) + +Pass *llvm::createLowerWidenableConditionPass() { + return new LowerWidenableConditionLegacyPass(); +} + +PreservedAnalyses LowerWidenableConditionPass::run(Function &F, + FunctionAnalysisManager &AM) { + if (lowerWidenableCondition(F)) + return PreservedAnalyses::none(); + + return PreservedAnalyses::all(); +} diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp index f3577726f98..c91ffda6d98 100644 --- a/lib/Transforms/Scalar/Scalar.cpp +++ b/lib/Transforms/Scalar/Scalar.cpp @@ -80,6 +80,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeLowerAtomicLegacyPassPass(Registry); initializeLowerExpectIntrinsicPass(Registry); initializeLowerGuardIntrinsicLegacyPassPass(Registry); + initializeLowerWidenableConditionLegacyPassPass(Registry); initializeMemCpyOptLegacyPassPass(Registry); initializeMergeICmpsPass(Registry); initializeMergedLoadStoreMotionLegacyPassPass(Registry); diff --git a/test/Transforms/LowerWidenableCondition/basic.ll b/test/Transforms/LowerWidenableCondition/basic.ll new file mode 100644 index 00000000000..9779efc8846 --- /dev/null +++ b/test/Transforms/LowerWidenableCondition/basic.ll @@ -0,0 +1,44 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -lower-widenable-condition < %s | FileCheck %s +; RUN: opt -S -passes=lower-widenable-condition < %s | FileCheck %s + +; Basic test case: make sure that all widenable conditions turn into i1 true. +define void @f_0(i1 %cond_0, i1 %cond_1) { +; CHECK-LABEL: @f_0( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], true +; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]] +; CHECK: deopt: +; CHECK-NEXT: unreachable +; CHECK: guarded: +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], true +; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]] +; CHECK: deopt2: +; CHECK-NEXT: unreachable +; CHECK: guarded1: +; 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 + unreachable + +guarded: ; preds = %entry + %widenable_cond3 = call i1 @llvm.experimental.widenable.condition() + %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3 + br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2 + +deopt2: ; preds = %guarded + unreachable + +guarded1: ; preds = %guarded + ret void +} + +; Function Attrs: inaccessiblememonly nounwind +declare i1 @llvm.experimental.widenable.condition() #0 + +attributes #0 = { inaccessiblememonly nounwind }