diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 1 |
2 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index cf997a8926c..2ab35645064 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -343,6 +343,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_MUL: + return narrowScalarMul(MI, TypeIdx, NarrowTy); case TargetOpcode::G_EXTRACT: { if (TypeIdx != 1) return UnableToLegalize; @@ -1527,6 +1529,51 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, } LegalizerHelper::LegalizeResult +LegalizerHelper::narrowScalarMul(MachineInstr &MI, unsigned TypeIdx, LLT NewTy) { + unsigned DstReg = MI.getOperand(0).getReg(); + unsigned Src0 = MI.getOperand(1).getReg(); + unsigned Src1 = MI.getOperand(2).getReg(); + LLT Ty = MRI.getType(DstReg); + if (Ty.isVector()) + return UnableToLegalize; + + unsigned Size = Ty.getSizeInBits(); + unsigned NewSize = Size / 2; + if (Size != 2 * NewSize) + return UnableToLegalize; + + LLT HalfTy = LLT::scalar(NewSize); + // TODO: if HalfTy != NewTy, handle the breakdown all at once? + + unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty); + unsigned Lo = MRI.createGenericVirtualRegister(HalfTy); + unsigned Hi = MRI.createGenericVirtualRegister(HalfTy); + unsigned ExtLo = MRI.createGenericVirtualRegister(Ty); + unsigned ExtHi = MRI.createGenericVirtualRegister(Ty); + unsigned ShiftedHi = MRI.createGenericVirtualRegister(Ty); + + SmallVector<unsigned, 2> Src0Parts; + SmallVector<unsigned, 2> Src1Parts; + + extractParts(Src0, HalfTy, 2, Src0Parts); + extractParts(Src1, HalfTy, 2, Src1Parts); + + MIRBuilder.buildMul(Lo, Src0Parts[0], Src1Parts[0]); + + // TODO: Use smulh or umulh depending on what the target has. + MIRBuilder.buildUMulH(Hi, Src0Parts[1], Src1Parts[1]); + + MIRBuilder.buildConstant(ShiftAmt, NewSize); + MIRBuilder.buildAnyExt(ExtHi, Hi); + MIRBuilder.buildShl(ShiftedHi, ExtHi, ShiftAmt); + + MIRBuilder.buildZExt(ExtLo, Lo); + MIRBuilder.buildOr(DstReg, ExtLo, ShiftedHi); + MI.eraseFromParent(); + return Legalized; +} + +LegalizerHelper::LegalizeResult LegalizerHelper::lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty) { unsigned Opc = MI.getOpcode(); auto &TII = *MI.getMF()->getSubtarget().getInstrInfo(); diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp index ecbfada17ba..9e6fa061c10 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -95,6 +95,7 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST, getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_UMULH, G_SMULH}) .legalFor({S32}) + .clampScalar(0, S32, S32) .scalarize(0); // Report legal for any types we can handle anywhere. For the cases only legal |

