Skip to content

Commit 71760f3

Browse files
authored
[CodeGen] Merge ExpandLargeDivRem into ExpandFp (#172680)
Both passes expand instructions at the IR level. They use the same kind of instruction visitation logic and contain significant code duplication e.g. for scalarization.
1 parent f125c8d commit 71760f3

37 files changed

+72
-265
lines changed

llvm/docs/WritingAnLLVMPass.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,6 @@ default optimization pipelines, e.g. (the output has been trimmed):
673673
ModulePass Manager
674674
Pre-ISel Intrinsic Lowering
675675
FunctionPass Manager
676-
Expand large div/rem
677676
Expand fp
678677
Expand Atomic instructions
679678
SVE intrinsics optimizations

llvm/include/llvm/CodeGen/ExpandLargeDivRem.h

Lines changed: 0 additions & 30 deletions
This file was deleted.

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,6 @@ LLVM_ABI FunctionPass *createExpandReductionsPass();
546546
// the corresponding function in a vector library (e.g., SVML, libmvec).
547547
LLVM_ABI FunctionPass *createReplaceWithVeclibLegacyPass();
548548

549-
// Expands large div/rem instructions.
550-
LLVM_ABI FunctionPass *createExpandLargeDivRemPass();
551-
552549
// Expands large div/rem instructions.
553550
LLVM_ABI FunctionPass *createExpandFpPass();
554551

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,7 +2219,7 @@ class LLVM_ABI TargetLoweringBase {
22192219
}
22202220

22212221
/// Returns the size in bits of the maximum div/rem the backend supports.
2222-
/// Larger operations will be expanded by ExpandLargeDivRem.
2222+
/// Larger operations will be expanded by ExpandFp.
22232223
unsigned getMaxDivRemBitWidthSupported() const {
22242224
return MaxDivRemBitWidthSupported;
22252225
}
@@ -2885,7 +2885,7 @@ class LLVM_ABI TargetLoweringBase {
28852885
}
28862886

28872887
/// Set the size in bits of the maximum div/rem the backend supports.
2888-
/// Larger operations will be expanded by ExpandLargeDivRem.
2888+
/// Larger operations will be expanded by ExpandFp.
28892889
void setMaxDivRemBitWidthSupported(unsigned SizeInBits) {
28902890
MaxDivRemBitWidthSupported = SizeInBits;
28912891
}
@@ -3742,7 +3742,7 @@ class LLVM_ABI TargetLoweringBase {
37423742
unsigned MaxAtomicSizeInBitsSupported;
37433743

37443744
/// Size in bits of the maximum div/rem size the backend supports.
3745-
/// Larger operations will be expanded by ExpandLargeDivRem.
3745+
/// Larger operations will be expanded by ExpandFp.
37463746
unsigned MaxDivRemBitWidthSupported;
37473747

37483748
/// Size in bits of the maximum fp to/from int conversion size the

llvm/include/llvm/InitializePasses.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ LLVM_ABI void initializeEarlyTailDuplicateLegacyPass(PassRegistry &);
113113
LLVM_ABI void initializeEdgeBundlesWrapperLegacyPass(PassRegistry &);
114114
LLVM_ABI void initializeEHContGuardTargetsPass(PassRegistry &);
115115
LLVM_ABI void initializeExpandFpLegacyPassPass(PassRegistry &);
116-
LLVM_ABI void initializeExpandLargeDivRemLegacyPassPass(PassRegistry &);
117116
LLVM_ABI void initializeExpandMemCmpLegacyPassPass(PassRegistry &);
118117
LLVM_ABI void initializeExpandPostRALegacyPass(PassRegistry &);
119118
LLVM_ABI void initializeExpandReductionsPass(PassRegistry &);

llvm/include/llvm/LinkAllPasses.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ struct ForcePassLinking {
128128
(void)llvm::createGVNPass();
129129
(void)llvm::createPostDomTree();
130130
(void)llvm::createMergeICmpsLegacyPass();
131-
(void)llvm::createExpandLargeDivRemPass();
132131
(void)llvm::createExpandMemCmpLegacyPass();
133132
std::string buf;
134133
llvm::raw_string_ostream os(buf);

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "llvm/CodeGen/DwarfEHPrepare.h"
3434
#include "llvm/CodeGen/EarlyIfConversion.h"
3535
#include "llvm/CodeGen/ExpandFp.h"
36-
#include "llvm/CodeGen/ExpandLargeDivRem.h"
3736
#include "llvm/CodeGen/ExpandMemCmp.h"
3837
#include "llvm/CodeGen/ExpandPostRAPseudos.h"
3938
#include "llvm/CodeGen/ExpandReductions.h"
@@ -678,7 +677,6 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPasses(
678677
addModulePass(LowerEmuTLSPass(), PMW);
679678

680679
addModulePass(PreISelIntrinsicLoweringPass(&TM), PMW);
681-
addFunctionPass(ExpandLargeDivRemPass(TM), PMW);
682680
addFunctionPass(ExpandFpPass(TM, getOptLevel()), PMW);
683681

684682
derived().addIRPasses(PMW);

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ add_llvm_component_library(LLVMCodeGen
5757
EdgeBundles.cpp
5858
EHContGuardTargets.cpp
5959
ExecutionDomainFix.cpp
60-
ExpandLargeDivRem.cpp
6160
ExpandFp.cpp
6261
ExpandMemCmp.cpp
6362
ExpandPostRAPseudos.cpp

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
3939
initializeEarlyIfPredicatorPass(Registry);
4040
initializeEarlyMachineLICMPass(Registry);
4141
initializeEarlyTailDuplicateLegacyPass(Registry);
42-
initializeExpandLargeDivRemLegacyPassPass(Registry);
4342
initializeExpandFpLegacyPassPass(Registry);
4443
initializeExpandMemCmpLegacyPassPass(Registry);
4544
initializeExpandPostRALegacyPass(Registry);

llvm/lib/CodeGen/ExpandFp.cpp

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
// useful for targets like x86_64 that cannot lower fp convertions
1313
// with more than 128 bits.
1414
//
15+
// This pass also expands div/rem instructions with a bitwidth above a
16+
// threshold into a call to auto-generated functions. This is useful
17+
// for targets like x86_64 that cannot lower divisions with more than
18+
// 128 bits or targets like x86_32 that cannot lower divisions with
19+
// more than 64 bits.
20+
//
1521
//===----------------------------------------------------------------------===//
1622

1723
#include "llvm/CodeGen/ExpandFp.h"
@@ -35,6 +41,8 @@
3541
#include "llvm/Support/ErrorHandling.h"
3642
#include "llvm/Target/TargetMachine.h"
3743
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
44+
#include "llvm/Transforms/Utils/IntegerDivision.h"
45+
#include <llvm/Support/Casting.h>
3846
#include <optional>
3947

4048
#define DEBUG_TYPE "expand-fp"
@@ -47,7 +55,28 @@ static cl::opt<unsigned>
4755
cl::desc("fp convert instructions on integers with "
4856
"more than <N> bits are expanded."));
4957

58+
static cl::opt<unsigned>
59+
ExpandDivRemBits("expand-div-rem-bits", cl::Hidden,
60+
cl::init(llvm::IntegerType::MAX_INT_BITS),
61+
cl::desc("div and rem instructions on integers with "
62+
"more than <N> bits are expanded."));
63+
5064
namespace {
65+
bool isConstantPowerOfTwo(llvm::Value *V, bool SignedOp) {
66+
auto *C = dyn_cast<ConstantInt>(V);
67+
if (!C)
68+
return false;
69+
70+
APInt Val = C->getValue();
71+
if (SignedOp && Val.isNegative())
72+
Val = -Val;
73+
return Val.isPowerOf2();
74+
}
75+
76+
bool isSigned(unsigned int Opcode) {
77+
return Opcode == Instruction::SDiv || Opcode == Instruction::SRem;
78+
}
79+
5180
/// This class implements a precise expansion of the frem instruction.
5281
/// The generated code is based on the fmod implementation in the AMD device
5382
/// libs.
@@ -995,11 +1024,17 @@ static bool runImpl(Function &F, const TargetLowering &TLI,
9951024
if (ExpandFpConvertBits != llvm::IntegerType::MAX_INT_BITS)
9961025
MaxLegalFpConvertBitWidth = ExpandFpConvertBits;
9971026

1027+
unsigned MaxLegalDivRemBitWidth = TLI.getMaxDivRemBitWidthSupported();
1028+
if (ExpandDivRemBits != llvm::IntegerType::MAX_INT_BITS)
1029+
MaxLegalDivRemBitWidth = ExpandDivRemBits;
1030+
9981031
bool DisableExpandLargeFp =
9991032
MaxLegalFpConvertBitWidth >= llvm::IntegerType::MAX_INT_BITS;
1033+
bool DisableExpandLargeDivRem =
1034+
MaxLegalDivRemBitWidth >= llvm::IntegerType::MAX_INT_BITS;
10001035
bool DisableFrem = !FRemExpander::shouldExpandAnyFremType(TLI);
10011036

1002-
if (DisableExpandLargeFp && DisableFrem)
1037+
if (DisableExpandLargeFp && DisableFrem && DisableExpandLargeDivRem)
10031038
return false;
10041039

10051040
auto ShouldHandleInst = [&](Instruction &I) {
@@ -1021,6 +1056,16 @@ static bool runImpl(Function &F, const TargetLowering &TLI,
10211056
return !DisableExpandLargeFp &&
10221057
cast<IntegerType>(I.getOperand(0)->getType()->getScalarType())
10231058
->getIntegerBitWidth() > MaxLegalFpConvertBitWidth;
1059+
case Instruction::UDiv:
1060+
case Instruction::SDiv:
1061+
case Instruction::URem:
1062+
case Instruction::SRem:
1063+
return !DisableExpandLargeDivRem &&
1064+
cast<IntegerType>(Ty->getScalarType())->getIntegerBitWidth() >
1065+
MaxLegalDivRemBitWidth
1066+
// The backend has peephole optimizations for powers of two.
1067+
// TODO: We don't consider vectors here.
1068+
&& !isConstantPowerOfTwo(I.getOperand(1), isSigned(I.getOpcode()));
10241069
}
10251070

10261071
return false;
@@ -1064,6 +1109,15 @@ static bool runImpl(Function &F, const TargetLowering &TLI,
10641109
case Instruction::SIToFP:
10651110
expandIToFP(I);
10661111
break;
1112+
1113+
case Instruction::UDiv:
1114+
case Instruction::SDiv:
1115+
expandDivision(cast<BinaryOperator>(I));
1116+
break;
1117+
case Instruction::URem:
1118+
case Instruction::SRem:
1119+
expandRemainder(cast<BinaryOperator>(I));
1120+
break;
10671121
}
10681122
}
10691123

0 commit comments

Comments
 (0)