summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp6
-rw-r--r--llvm/test/CodeGen/X86/umul-with-overflow.ll9
2 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index aee4194b86e..e664e06ccfd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -952,9 +952,11 @@ SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
SDValue Overflow;
if (N->getOpcode() == ISD::UMULO) {
// Unsigned overflow occurred if the high part is non-zero.
+ unsigned Shift = SmallVT.getScalarSizeInBits();
+ EVT ShiftTy = getShiftAmountTyForConstant(Shift, Mul.getValueType(),
+ TLI, DAG);
SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
- DAG.getIntPtrConstant(SmallVT.getSizeInBits(),
- DL));
+ DAG.getConstant(Shift, DL, ShiftTy));
Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
DAG.getConstant(0, DL, Hi.getValueType()),
ISD::SETNE);
diff --git a/llvm/test/CodeGen/X86/umul-with-overflow.ll b/llvm/test/CodeGen/X86/umul-with-overflow.ll
index 64a8933346e..c2a0dc047bc 100644
--- a/llvm/test/CodeGen/X86/umul-with-overflow.ll
+++ b/llvm/test/CodeGen/X86/umul-with-overflow.ll
@@ -68,3 +68,12 @@ entry:
%tmp2 = extractvalue { i32, i1 } %tmp1, 0
ret i32 %tmp2
}
+
+; Check that shifts larger than the shift amount type are handled.
+; Intentionally not testing codegen here, only that this doesn't assert.
+declare {i300, i1} @llvm.umul.with.overflow.i300(i300 %a, i300 %b)
+define i300 @test4(i300 %a, i300 %b) nounwind {
+ %x = call {i300, i1} @llvm.umul.with.overflow.i300(i300 %a, i300 %b)
+ %y = extractvalue {i300, i1} %x, 0
+ ret i300 %y
+}
OpenPOWER on IntegriCloud