void initializeLowerEmuTLSPass(PassRegistry&);
void initializeLowerExpectIntrinsicPass(PassRegistry&);
void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&);
+void initializeLowerWidenableConditionLegacyPassPass(PassRegistry&);
void initializeLowerIntrinsicsPass(PassRegistry&);
void initializeLowerInvokeLegacyPassPass(PassRegistry&);
void initializeLowerSwitchPass(PassRegistry&);
//
Pass *createLowerGuardIntrinsicPass();
+//===----------------------------------------------------------------------===//
+//
+// LowerWidenableCondition - Lower widenable condition to i1 true.
+//
+Pass *createLowerWidenableConditionPass();
+
//===----------------------------------------------------------------------===//
//
// MergeICmps - Merge integer comparison chains into a memcmp
--- /dev/null
+//===--- 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<LowerWidenableConditionPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+}
+
+#endif //LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H
#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"
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())
LowerAtomic.cpp
LowerExpectIntrinsic.cpp
LowerGuardIntrinsic.cpp
+ LowerWidenableCondition.cpp
MakeGuardsExplicit.cpp
MemCpyOptimizer.cpp
MergeICmps.cpp
--- /dev/null
+//===- 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<CallInst *, 8> ToLower;
+ for (auto &I : instructions(F))
+ if (match(&I, m_Intrinsic<Intrinsic::experimental_widenable_condition>()))
+ ToLower.push_back(cast<CallInst>(&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();
+}
initializeLowerAtomicLegacyPassPass(Registry);
initializeLowerExpectIntrinsicPass(Registry);
initializeLowerGuardIntrinsicLegacyPassPass(Registry);
+ initializeLowerWidenableConditionLegacyPassPass(Registry);
initializeMemCpyOptLegacyPassPass(Registry);
initializeMergeICmpsPass(Registry);
initializeMergedLoadStoreMotionLegacyPassPass(Registry);
--- /dev/null
+; 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 }