summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp47
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp1
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
OpenPOWER on IntegriCloud