diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h --- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h +++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h @@ -663,6 +663,10 @@ // Expand reduction intrinsics into shuffle sequences if the target wants to. addPass(ExpandReductionsPass()); + + // Convert conditional moves to conditional jumps when profitable. + if (getOptLevel() != CodeGenOpt::None && !Opt.DisableSelectOptimize) + addPass(SelectOptimizePass()); } /// Turn exception handling constructs into something the code generators can diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def --- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def +++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def @@ -120,6 +120,7 @@ DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ()) DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ()) DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ()) +DUMMY_FUNCTION_PASS("select-optimize", SelectOptimizePass, ()) #undef DUMMY_FUNCTION_PASS #ifndef DUMMY_MODULE_PASS diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -560,6 +560,9 @@ /// JMC instrument pass. ModulePass *createJMCInstrumenterPass(); + + /// This pass converts conditional moves to conditional jumps when profitable. + FunctionPass *createSelectOptimizePass(); } // End llvm namespace #endif diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -394,6 +394,7 @@ void initializeSafeStackLegacyPassPass(PassRegistry&); void initializeSafepointIRVerifierPass(PassRegistry&); void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&); +void initializeSelectOptimizePass(PassRegistry &); void initializeModuleSanitizerCoverageLegacyPassPass(PassRegistry &); void initializeScalarEvolutionWrapperPassPass(PassRegistry&); void initializeScalarizeMaskedMemIntrinLegacyPassPass(PassRegistry &); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -232,6 +232,7 @@ (void) llvm::createUnifyLoopExitsPass(); (void) llvm::createFixIrreduciblePass(); (void)llvm::createFunctionSpecializationPass(); + (void)llvm::createSelectOptimizePass(); (void)new llvm::IntervalPartition(); (void)new llvm::ScalarEvolutionWrapperPass(); diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h --- a/llvm/include/llvm/Target/CGPassBuilderOption.h +++ b/llvm/include/llvm/Target/CGPassBuilderOption.h @@ -42,6 +42,7 @@ bool DisableMergeICmps = false; bool DisablePartialLibcallInlining = false; bool DisableConstantHoisting = false; + bool DisableSelectOptimize = false; bool PrintISelInput = false; bool PrintGCInfo = false; bool RequiresCodeGenSCCOrder = false; diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -197,6 +197,7 @@ ScheduleDAGInstrs.cpp ScheduleDAGPrinter.cpp ScoreboardHazardRecognizer.cpp + SelectOptimize.cpp ShadowStackGCLowering.cpp ShrinkWrap.cpp SjLjEHPrepare.cpp diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -107,6 +107,7 @@ initializeRemoveRedundantDebugValuesPass(Registry); initializeRenameIndependentSubregsPass(Registry); initializeSafeStackLegacyPassPass(Registry); + initializeSelectOptimizePass(Registry); initializeShadowStackGCLoweringPass(Registry); initializeShrinkWrapPass(Registry); initializeSjLjEHPreparePass(Registry); diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/CodeGen/SelectOptimize.cpp @@ -0,0 +1,43 @@ +//===--- SelectOptimize.cpp - Convert select to branches if profitable ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This pass converts selects to conditional jumps when profitable. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Function.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" + +using namespace llvm; + +namespace { + +class SelectOptimize : public FunctionPass { +public: + static char ID; + SelectOptimize() : FunctionPass(ID) { + initializeSelectOptimizePass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override {} +}; +} // namespace + +char SelectOptimize::ID = 0; +INITIALIZE_PASS(SelectOptimize, "select-optimize", "Optimize selects", false, + false) + +FunctionPass *llvm::createSelectOptimizePass() { return new SelectOptimize(); } + +bool SelectOptimize::runOnFunction(Function &F) { + llvm_unreachable("Unimplemented"); +} diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -260,6 +260,11 @@ "disable-expand-reductions", cl::init(false), cl::Hidden, cl::desc("Disable the expand reduction intrinsics pass from running")); +/// Disable the select optimization pass. +static cl::opt DisableSelectOptimize( + "disable-select-optimize", cl::init(true), cl::Hidden, + cl::desc("Disable the select-optimization pass from running")); + /// Allow standard passes to be disabled by command line options. This supports /// simple binary flags that either suppress the pass or do nothing. /// i.e. -disable-mypass=false has no effect. @@ -494,6 +499,7 @@ SET_BOOLEAN_OPTION(DisableConstantHoisting) SET_BOOLEAN_OPTION(DisableCGP) SET_BOOLEAN_OPTION(DisablePartialLibcallInlining) + SET_BOOLEAN_OPTION(DisableSelectOptimize) SET_BOOLEAN_OPTION(PrintLSR) SET_BOOLEAN_OPTION(PrintISelInput) SET_BOOLEAN_OPTION(PrintGCInfo) @@ -935,6 +941,10 @@ if (getOptLevel() != CodeGenOpt::None) addPass(createTLSVariableHoistPass()); + + // Convert conditional moves to conditional jumps when profitable. + if (getOptLevel() != CodeGenOpt::None && !DisableSelectOptimize) + addPass(createSelectOptimizePass()); } /// Turn exception handling constructs into something the code generators can diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -493,7 +493,8 @@ "polyhedral-info", "print-polyhedral-info", "replace-with-veclib", "jmc-instrument", "dot-regions", "dot-regions-only", - "view-regions", "view-regions-only"}; + "view-regions", "view-regions-only", + "select-optimize"}; for (const auto &P : PassNamePrefix) if (Pass.startswith(P)) return true; @@ -544,6 +545,7 @@ // supported. initializeExpandMemCmpPassPass(Registry); initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry); + initializeSelectOptimizePass(Registry); initializeCodeGenPreparePass(Registry); initializeAtomicExpandPass(Registry); initializeRewriteSymbolsLegacyPassPass(Registry);