31#define GET_GICOMBINER_DEPS
32#include "AMDGPUGenPreLegalizeGICombiner.inc"
33#undef GET_GICOMBINER_DEPS
35#define DEBUG_TYPE "amdgpu-regbank-combiner"
41#define GET_GICOMBINER_TYPES
42#include "AMDGPUGenRegBankGICombiner.inc"
43#undef GET_GICOMBINER_TYPES
45class AMDGPURegBankCombinerImpl :
public Combiner {
47 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig;
55 AMDGPURegBankCombinerImpl(
58 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig,
62 static const char *
getName() {
return "AMDGPURegBankCombinerImpl"; }
70 unsigned Min, Max, Med;
73 struct Med3MatchInfo {
78 struct MinMaxToMinMax3MatchInfo {
83 MinMaxMedOpc getMinMaxPair(
unsigned Opc)
const;
85 template <
class m_Cst,
typename CstTy>
87 Register &Val, CstTy &K0, CstTy &K1)
const;
89 bool matchIntMinMaxToMed3(
MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const;
90 bool matchFPMinMaxToMed3(
MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const;
104 MinMaxToMinMax3MatchInfo &MatchInfo)
const;
106 MinMaxToMinMax3MatchInfo &MatchInfo)
const;
110 bool getIEEE()
const;
111 bool getDX10Clamp()
const;
118#define GET_GICOMBINER_CLASS_MEMBERS
119#define AMDGPUSubtarget GCNSubtarget
120#include "AMDGPUGenRegBankGICombiner.inc"
121#undef GET_GICOMBINER_CLASS_MEMBERS
122#undef AMDGPUSubtarget
125#define GET_GICOMBINER_IMPL
126#define AMDGPUSubtarget GCNSubtarget
127#include "AMDGPUGenRegBankGICombiner.inc"
128#undef AMDGPUSubtarget
129#undef GET_GICOMBINER_IMPL
131AMDGPURegBankCombinerImpl::AMDGPURegBankCombinerImpl(
134 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig,
136 :
Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
137 RBI(*STI.getRegBankInfo()),
TRI(*STI.getRegisterInfo()),
138 TII(*STI.getInstrInfo()),
139 Helper(Observer,
B,
false, &VT, MDT, LI),
141#include
"AMDGPUGenRegBankGICombiner.inc"
146bool AMDGPURegBankCombinerImpl::isVgprRegBank(
Register Reg)
const {
151 if (isVgprRegBank(
Reg))
157 if (
Use.getOpcode() == AMDGPU::COPY && isVgprRegBank(Def))
167AMDGPURegBankCombinerImpl::MinMaxMedOpc
168AMDGPURegBankCombinerImpl::getMinMaxPair(
unsigned Opc)
const {
174 return {AMDGPU::G_SMIN, AMDGPU::G_SMAX, AMDGPU::G_AMDGPU_SMED3};
177 return {AMDGPU::G_UMIN, AMDGPU::G_UMAX, AMDGPU::G_AMDGPU_UMED3};
178 case AMDGPU::G_FMAXNUM:
179 case AMDGPU::G_FMINNUM:
180 return {AMDGPU::G_FMINNUM, AMDGPU::G_FMAXNUM, AMDGPU::G_AMDGPU_FMED3};
181 case AMDGPU::G_FMAXNUM_IEEE:
182 case AMDGPU::G_FMINNUM_IEEE:
183 return {AMDGPU::G_FMINNUM_IEEE, AMDGPU::G_FMAXNUM_IEEE,
184 AMDGPU::G_AMDGPU_FMED3};
188template <
class m_Cst,
typename CstTy>
189bool AMDGPURegBankCombinerImpl::matchMed(MachineInstr &
MI,
190 MachineRegisterInfo &
MRI,
192 CstTy &K0, CstTy &K1)
const {
210bool AMDGPURegBankCombinerImpl::matchIntMinMaxToMed3(
211 MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const {
213 if (!isVgprRegBank(Dst))
221 MinMaxMedOpc OpcodeTriple = getMinMaxPair(
MI.getOpcode());
223 std::optional<ValueAndVReg> K0, K1;
225 if (!matchMed<GCstAndRegMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
228 if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_SMED3 && K0->Value.sgt(K1->Value))
230 if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_UMED3 && K0->Value.ugt(K1->Value))
233 MatchInfo = {OpcodeTriple.Med, Val, K0->VReg, K1->VReg};
255bool AMDGPURegBankCombinerImpl::matchFPMinMaxToMed3(
256 MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const {
259 if (!isVgprRegBank(Dst))
268 auto OpcodeTriple = getMinMaxPair(
MI.getOpcode());
271 std::optional<FPValueAndVReg> K0, K1;
273 if (!matchMed<GFCstAndRegMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
276 if (K0->Value > K1->Value)
286 if ((getIEEE() && isFminnumLike(
MI)) || VT->isKnownNeverNaN(Dst)) {
290 MatchInfo = {OpcodeTriple.Med, Val, K0->VReg, K1->VReg};
298bool AMDGPURegBankCombinerImpl::matchFPMinMaxToClamp(MachineInstr &
MI,
301 if (!isVgprRegBank(
MI.getOperand(0).getReg()))
305 auto OpcodeTriple = getMinMaxPair(
MI.getOpcode());
307 std::optional<FPValueAndVReg> K0, K1;
309 if (!matchMed<GFCstOrSplatGFCstMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
312 if (!K0->Value.isPosZero() || !K1->Value.isOne())
319 if ((getIEEE() && getDX10Clamp() && isFminnumLike(
MI) &&
320 VT->isKnownNeverSNaN(Val)) ||
321 VT->isKnownNeverNaN(
MI.getOperand(0).getReg())) {
338bool AMDGPURegBankCombinerImpl::matchFPMed3ToClamp(MachineInstr &
MI,
341 if (!isVgprRegBank(
MI.getOperand(0).getReg()))
350 if (isFCst(Src0) && !isFCst(Src1))
352 if (isFCst(Src1) && !isFCst(Src2))
354 if (isFCst(Src0) && !isFCst(Src1))
361 auto isOp3Zero = [&]() {
363 if (Op3->
getOpcode() == TargetOpcode::G_FCONSTANT)
371 if (VT->isKnownNeverNaN(
MI.getOperand(0).getReg()) ||
372 (getIEEE() && getDX10Clamp() &&
373 (VT->isKnownNeverSNaN(Val) || isOp3Zero()))) {
381void AMDGPURegBankCombinerImpl::applyClamp(MachineInstr &
MI,
383 B.buildInstr(AMDGPU::G_AMDGPU_CLAMP, {
MI.getOperand(0)}, {
Reg},
385 MI.eraseFromParent();
388void AMDGPURegBankCombinerImpl::applyMed3(MachineInstr &
MI,
389 Med3MatchInfo &MatchInfo)
const {
390 B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
391 {getAsVgpr(MatchInfo.Val0), getAsVgpr(MatchInfo.Val1),
392 getAsVgpr(MatchInfo.Val2)},
394 MI.eraseFromParent();
397void AMDGPURegBankCombinerImpl::applyCanonicalizeZextShiftAmt(
398 MachineInstr &
MI, MachineInstr &Ext)
const {
399 unsigned ShOpc =
MI.getOpcode();
400 assert(ShOpc == AMDGPU::G_SHL || ShOpc == AMDGPU::G_LSHR ||
401 ShOpc == AMDGPU::G_ASHR);
413 auto NewExt =
B.buildAnyExt(ExtAmtTy, AmtReg);
414 auto Mask =
B.buildConstant(
416 auto And =
B.buildAnd(ExtAmtTy, NewExt, Mask);
417 B.buildInstr(ShOpc, {ShDst}, {ShSrc,
And});
422 MI.eraseFromParent();
425bool AMDGPURegBankCombinerImpl::combineD16Load(MachineInstr &
MI)
const {
430 const MachineMemOperand *MMO;
431 const int64_t CleanLo16 = 0xFFFFFFFFFFFF0000;
432 const int64_t CleanHi16 = 0x000000000000FFFF;
434 auto TryApplyD16Load = [&](
unsigned D16Opc, GAnyLoad *SmallLoad) {
441 MachineInstr *InsertPt = SmallLoad;
442 if (SmallLoad->isSimple() && isObviouslySafeToFold(*SmallLoad,
MI))
444 else if (!Helper.
dominates(*DstDef, *SmallLoad))
447 applyD16Load(D16Opc,
MI, SmallLoad, Dst, *InsertPt);
459 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO_U8, ZextLoad);
461 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO, ZextLoad);
477 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO_I8, SextLoad);
492 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI_U8, ZextLoad);
494 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI, ZextLoad);
509 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI_I8, SextLoad);
518void AMDGPURegBankCombinerImpl::applyMinMaxToMinMax3(
519 MachineInstr &
MI, MinMaxToMinMax3MatchInfo &MatchInfo)
const {
520 B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
521 {MatchInfo.Val0, MatchInfo.Val1, MatchInfo.Val2},
MI.getFlags());
522 MI.eraseFromParent();
528bool AMDGPURegBankCombinerImpl::matchMinMaxToMinMax3(
529 MachineInstr &
MI, MinMaxToMinMax3MatchInfo &MatchInfo)
const {
534 if (!(isVgprRegBank(Dst) && isVgprRegBank(Src1) && isVgprRegBank(Src2))) {
539 unsigned Opc =
MI.getOpcode();
552 unsigned AMDGPUOpc = 0;
555 AMDGPUOpc = AMDGPU::G_AMDGPU_SMAX3;
558 AMDGPUOpc = AMDGPU::G_AMDGPU_SMIN3;
561 AMDGPUOpc = AMDGPU::G_AMDGPU_UMAX3;
564 AMDGPUOpc = AMDGPU::G_AMDGPU_UMIN3;
566 case AMDGPU::G_FMAXNUM:
567 case AMDGPU::G_FMAXNUM_IEEE:
568 case AMDGPU::G_FMAXIMUMNUM:
569 AMDGPUOpc = AMDGPU::G_AMDGPU_FMAX3;
571 case AMDGPU::G_FMINNUM:
572 case AMDGPU::G_FMINNUM_IEEE:
573 case AMDGPU::G_FMINIMUMNUM:
574 AMDGPUOpc = AMDGPU::G_AMDGPU_FMIN3;
576 case AMDGPU::G_FMAXIMUM:
577 AMDGPUOpc = AMDGPU::G_AMDGPU_FMAXIMUM3;
579 case AMDGPU::G_FMINIMUM:
580 AMDGPUOpc = AMDGPU::G_AMDGPU_FMINIMUM3;
586 MatchInfo = {AMDGPUOpc, R0, R1,
R2};
590void AMDGPURegBankCombinerImpl::applyD16Load(
unsigned D16Opc,
592 MachineInstr *SmallLoad,
594 MachineInstr &InsertPt)
const {
596 LLT SrcTy =
MRI.
getType(SrcReg32ToOverwriteD16);
604 B.setInstrAndDebugLoc(InsertPt);
606 B.buildInstr(D16Opc, {D16Dst},
610 if (D16Dst != DstReg)
611 B.buildBitcast(DstReg, D16Dst);
621SIModeRegisterDefaults AMDGPURegBankCombinerImpl::getMode()
const {
622 return MF.getInfo<SIMachineFunctionInfo>()->getMode();
625bool AMDGPURegBankCombinerImpl::getIEEE()
const {
return getMode().IEEE; }
627bool AMDGPURegBankCombinerImpl::getDX10Clamp()
const {
628 return getMode().DX10Clamp;
631bool AMDGPURegBankCombinerImpl::isFminnumIeee(
const MachineInstr &
MI)
const {
632 return MI.getOpcode() == AMDGPU::G_FMINNUM_IEEE;
635bool AMDGPURegBankCombinerImpl::isFminnum(
const MachineInstr &
MI)
const {
636 return MI.getOpcode() == AMDGPU::G_FMINNUM;
639bool AMDGPURegBankCombinerImpl::isFminnumLike(
const MachineInstr &
MI)
const {
640 return isFminnumIeee(
MI) || isFminnum(
MI);
643bool AMDGPURegBankCombinerImpl::isFCst(MachineInstr *
MI)
const {
644 return MI->getOpcode() == AMDGPU::G_FCONSTANT;
647bool AMDGPURegBankCombinerImpl::isClampZeroToOne(MachineInstr *K0,
648 MachineInstr *K1)
const {
649 if (isFCst(K0) && isFCst(K1)) {
659 function_ref<GISelValueTracking *()> GetVT,
660 function_ref<MachineDominatorTree *()> GetMDT,
662 AMDGPURegBankCombinerImplRuleConfig RuleConfig;
663 if (!RuleConfig.parseCommandLineOption())
671 const auto *LI =
ST.getLegalizerInfo();
673 CombinerInfo CInfo(
false,
true,
674 LI, EnableOpt,
F.hasOptSize(),
F.hasMinSize());
676 CInfo.MaxIterations = 1;
677 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
680 CInfo.EnableFullDCE =
false;
682 GISelValueTracking *VT = GetVT();
683 MachineDominatorTree *MDT = GetMDT();
684 AMDGPURegBankCombinerImpl Impl(MF, CInfo, *VT,
nullptr,
685 RuleConfig, ST, MDT, LI);
686 return Impl.combineMachineInstrs();
692class AMDGPURegBankCombinerLegacy :
public MachineFunctionPass {
696 AMDGPURegBankCombinerLegacy(
bool IsOptLevelNone =
false)
697 : MachineFunctionPass(
ID), IsOptLevelNone(IsOptLevelNone) {}
699 StringRef getPassName()
const override {
return "AMDGPURegBankCombiner"; }
703 void getAnalysisUsage(AnalysisUsage &AU)
const override;
710void AMDGPURegBankCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU)
const {
713 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
715 if (!IsOptLevelNone) {
721bool AMDGPURegBankCombinerLegacy::runOnMachineFunction(
MachineFunction &MF) {
729 return &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
731 [&]() -> MachineDominatorTree * {
732 return IsOptLevelNone ? nullptr
733 : &getAnalysis<MachineDominatorTreeWrapperPass>()
739char AMDGPURegBankCombinerLegacy::ID = 0;
741 "Combine AMDGPU machine instrs after regbankselect",
745 "Combine AMDGPU machine instrs after regbankselect",
false,
749 return new AMDGPURegBankCombinerLegacy(IsOptLevelNone);
753 : IsOptLevelNone(IsOptLevelNone) {}
765 return IsOptLevelNone
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
This file declares the targeting of the Machinelegalizer class for AMDGPU.
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
AMD GCN specific subclass of TargetSubtarget.
Provides analysis for querying information about KnownBits during GISel passes.
const HexagonInstrInfo * TII
Contains matchers for matching SSA Machine Instructions.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static StringRef getName(Value *V)
MachineRegisterInfo & MRI
static bool isClampZeroToOne(SDValue A, SDValue B)
Target-Independent Code Generator Pass Configuration Options pass.
AMDGPURegBankCombinerPass(bool IsOptLevelNone=false)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
LLVM_ABI bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI) const
Returns true if DefMI dominates UseMI.
bool isPosZero() const
Return true if the value is positive zero.
bool isOne() const
Returns true if this value is exactly +1.0.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMin3Max3_16() const
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT float16()
Get a 16-bit IEEE half value.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
static LLT integer(unsigned SizeInBits)
TypeSize getValue() const
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LocationSize getSizeInBits() const
Return the size in bits of the memory reference.
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const RegisterBank * getRegBank(Register Reg) const
Return the register bank of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Holds all the information related to register banks.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
LoadOp_match< GZExtLoad, operand_type_match > m_GZExtLoad(GZExtLoad *&Inst)
LoadOp_match< GSExtLoad, operand_type_match > m_GSExtLoad(GSExtLoad *&Inst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
CheckType m_SpecificType(LLT Ty)
BinaryOpc_match< LHS, RHS, true > m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R)
MMORef m_MMO(const MachineMemOperand *&MMO)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
And< Preds... > m_all_of(Preds &&... preds)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
@ Load
The value being inserted comes from a load (InsertElement only).
FunctionPass * createAMDGPURegBankCombinerLegacy(bool IsOptLevelNone)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
@ And
Bitwise or logical AND of integers.
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)