Skip to content

Commit f392bc8

Browse files
author
Max Kazantsev
committed
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 llvm-svn: 352739
1 parent ae29857 commit f392bc8

File tree

9 files changed

+168
-0
lines changed

9 files changed

+168
-0
lines changed

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ void initializeLowerAtomicLegacyPassPass(PassRegistry&);
240240
void initializeLowerEmuTLSPass(PassRegistry&);
241241
void initializeLowerExpectIntrinsicPass(PassRegistry&);
242242
void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&);
243+
void initializeLowerWidenableConditionLegacyPassPass(PassRegistry&);
243244
void initializeLowerIntrinsicsPass(PassRegistry&);
244245
void initializeLowerInvokeLegacyPassPass(PassRegistry&);
245246
void initializeLowerSwitchPass(PassRegistry&);

llvm/include/llvm/Transforms/Scalar.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,12 @@ Pass *createLowerAtomicPass();
357357
//
358358
Pass *createLowerGuardIntrinsicPass();
359359

360+
//===----------------------------------------------------------------------===//
361+
//
362+
// LowerWidenableCondition - Lower widenable condition to i1 true.
363+
//
364+
Pass *createLowerWidenableConditionPass();
365+
360366
//===----------------------------------------------------------------------===//
361367
//
362368
// MergeICmps - Merge integer comparison chains into a memcmp
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===--- LowerWidenableCondition.h - Lower the guard intrinsic ---------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This pass lowers the llvm.widenable.condition intrinsic to default value
11+
// which is i1 true.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
#ifndef LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H
15+
#define LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H
16+
17+
#include "llvm/IR/PassManager.h"
18+
19+
namespace llvm {
20+
21+
struct LowerWidenableConditionPass : PassInfoMixin<LowerWidenableConditionPass> {
22+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
23+
};
24+
25+
}
26+
27+
#endif //LLVM_TRANSFORMS_SCALAR_LOWERWIDENABLECONDITION_H

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#include "llvm/Transforms/Scalar/LowerAtomic.h"
134134
#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
135135
#include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
136+
#include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
136137
#include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
137138
#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
138139
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass())
177177
FUNCTION_PASS("loweratomic", LowerAtomicPass())
178178
FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
179179
FUNCTION_PASS("lower-guard-intrinsic", LowerGuardIntrinsicPass())
180+
FUNCTION_PASS("lower-widenable-condition", LowerWidenableConditionPass())
180181
FUNCTION_PASS("guard-widening", GuardWideningPass())
181182
FUNCTION_PASS("gvn", GVN())
182183
FUNCTION_PASS("load-store-vectorizer", LoadStoreVectorizerPass())

llvm/lib/Transforms/Scalar/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ add_llvm_library(LLVMScalarOpts
4545
LowerAtomic.cpp
4646
LowerExpectIntrinsic.cpp
4747
LowerGuardIntrinsic.cpp
48+
LowerWidenableCondition.cpp
4849
MakeGuardsExplicit.cpp
4950
MemCpyOptimizer.cpp
5051
MergeICmps.cpp
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//===- LowerWidenableCondition.cpp - Lower the guard intrinsic ---------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This pass lowers the llvm.widenable.condition intrinsic to default value
11+
// which is i1 true.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
16+
#include "llvm/ADT/SmallVector.h"
17+
#include "llvm/Analysis/GuardUtils.h"
18+
#include "llvm/IR/BasicBlock.h"
19+
#include "llvm/IR/Function.h"
20+
#include "llvm/IR/InstIterator.h"
21+
#include "llvm/IR/Instructions.h"
22+
#include "llvm/IR/Intrinsics.h"
23+
#include "llvm/IR/Module.h"
24+
#include "llvm/IR/PatternMatch.h"
25+
#include "llvm/Pass.h"
26+
#include "llvm/Transforms/Scalar.h"
27+
#include "llvm/Transforms/Utils/GuardUtils.h"
28+
29+
using namespace llvm;
30+
31+
namespace {
32+
struct LowerWidenableConditionLegacyPass : public FunctionPass {
33+
static char ID;
34+
LowerWidenableConditionLegacyPass() : FunctionPass(ID) {
35+
initializeLowerWidenableConditionLegacyPassPass(
36+
*PassRegistry::getPassRegistry());
37+
}
38+
39+
bool runOnFunction(Function &F) override;
40+
};
41+
}
42+
43+
static bool lowerWidenableCondition(Function &F) {
44+
// Check if we can cheaply rule out the possibility of not having any work to
45+
// do.
46+
auto *WCDecl = F.getParent()->getFunction(
47+
Intrinsic::getName(Intrinsic::experimental_widenable_condition));
48+
if (!WCDecl || WCDecl->use_empty())
49+
return false;
50+
51+
using namespace llvm::PatternMatch;
52+
SmallVector<CallInst *, 8> ToLower;
53+
for (auto &I : instructions(F))
54+
if (match(&I, m_Intrinsic<Intrinsic::experimental_widenable_condition>()))
55+
ToLower.push_back(cast<CallInst>(&I));
56+
57+
if (ToLower.empty())
58+
return false;
59+
60+
for (auto *CI : ToLower) {
61+
CI->replaceAllUsesWith(ConstantInt::getTrue(CI->getContext()));
62+
CI->eraseFromParent();
63+
}
64+
return true;
65+
}
66+
67+
bool LowerWidenableConditionLegacyPass::runOnFunction(Function &F) {
68+
return lowerWidenableCondition(F);
69+
}
70+
71+
char LowerWidenableConditionLegacyPass::ID = 0;
72+
INITIALIZE_PASS(LowerWidenableConditionLegacyPass, "lower-widenable-condition",
73+
"Lower the widenable condition to default true value", false,
74+
false)
75+
76+
Pass *llvm::createLowerWidenableConditionPass() {
77+
return new LowerWidenableConditionLegacyPass();
78+
}
79+
80+
PreservedAnalyses LowerWidenableConditionPass::run(Function &F,
81+
FunctionAnalysisManager &AM) {
82+
if (lowerWidenableCondition(F))
83+
return PreservedAnalyses::none();
84+
85+
return PreservedAnalyses::all();
86+
}

llvm/lib/Transforms/Scalar/Scalar.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
8080
initializeLowerAtomicLegacyPassPass(Registry);
8181
initializeLowerExpectIntrinsicPass(Registry);
8282
initializeLowerGuardIntrinsicLegacyPassPass(Registry);
83+
initializeLowerWidenableConditionLegacyPassPass(Registry);
8384
initializeMemCpyOptLegacyPassPass(Registry);
8485
initializeMergeICmpsPass(Registry);
8586
initializeMergedLoadStoreMotionLegacyPassPass(Registry);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -lower-widenable-condition < %s | FileCheck %s
3+
; RUN: opt -S -passes=lower-widenable-condition < %s | FileCheck %s
4+
5+
; Basic test case: make sure that all widenable conditions turn into i1 true.
6+
define void @f_0(i1 %cond_0, i1 %cond_1) {
7+
; CHECK-LABEL: @f_0(
8+
; CHECK-NEXT: entry:
9+
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], true
10+
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]]
11+
; CHECK: deopt:
12+
; CHECK-NEXT: unreachable
13+
; CHECK: guarded:
14+
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], true
15+
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]]
16+
; CHECK: deopt2:
17+
; CHECK-NEXT: unreachable
18+
; CHECK: guarded1:
19+
; CHECK-NEXT: ret void
20+
;
21+
entry:
22+
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
23+
%exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
24+
br i1 %exiplicit_guard_cond, label %guarded, label %deopt
25+
26+
deopt: ; preds = %entry
27+
unreachable
28+
29+
guarded: ; preds = %entry
30+
%widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
31+
%exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
32+
br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2
33+
34+
deopt2: ; preds = %guarded
35+
unreachable
36+
37+
guarded1: ; preds = %guarded
38+
ret void
39+
}
40+
41+
; Function Attrs: inaccessiblememonly nounwind
42+
declare i1 @llvm.experimental.widenable.condition() #0
43+
44+
attributes #0 = { inaccessiblememonly nounwind }

0 commit comments

Comments
 (0)