diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h @@ -47,6 +47,8 @@ MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const; bool legalizeVectorTrunc(MachineInstr &MI, LegalizerHelper &Helper) const; + bool legalizeBitfieldExtract(MachineInstr &MI, MachineRegisterInfo &MRI, + LegalizerHelper &Helper) const; const AArch64Subtarget *ST; }; } // End llvm namespace. diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -702,7 +702,8 @@ getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower(); - getActionDefinitionsBuilder({G_SBFX, G_UBFX}).legalFor({s32, s64}); + getActionDefinitionsBuilder({G_SBFX, G_UBFX}).customFor({s32, s64}); + computeTables(); verify(*ST.getInstrInfo()); } @@ -729,6 +730,9 @@ return legalizeSmallCMGlobalValue(MI, MRI, MIRBuilder, Observer); case TargetOpcode::G_TRUNC: return legalizeVectorTrunc(MI, Helper); + case TargetOpcode::G_SBFX: + case TargetOpcode::G_UBFX: + return legalizeBitfieldExtract(MI, MRI, Helper); } llvm_unreachable("expected switch to return"); @@ -948,3 +952,11 @@ MI.eraseFromParent(); return true; } + +bool AArch64LegalizerInfo::legalizeBitfieldExtract( + MachineInstr &MI, MachineRegisterInfo &MRI, LegalizerHelper &Helper) const { + // Only legal if we can select immediate forms. + // TODO: Lower this otherwise. + return getConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI) && + getConstantVRegValWithLookThrough(MI.getOperand(3).getReg(), MRI); +}