[llvm-commits] [llvm] r125748 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Duncan Sands
baldrick at free.fr
Thu Feb 17 04:42:48 PST 2011
Author: baldrick
Date: Thu Feb 17 06:42:48 2011
New Revision: 125748
URL: http://llvm.org/viewvc/llvm-project?rev=125748&view=rev
Log:
Fix wrong logic in promotion of signed mul-with-overflow (I pointed this out at
the time but presumably my email got lost). Examples where the previous logic
got it wrong: (1) a signed i8 multiply of 64 by 2 overflows, but the high part is
zero; (2) a signed i8 multiple of -128 by 2 overflows, but the high part is all
ones.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=125748&r1=125747&r2=125748&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Thu Feb 17 06:42:48 2011
@@ -548,16 +548,15 @@
return Res;
}
-
SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
// Promote the overflow bit trivially.
if (ResNo == 1)
return PromoteIntRes_Overflow(N);
-
+
SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
DebugLoc DL = N->getDebugLoc();
- unsigned SmallSize = LHS.getValueType().getSizeInBits();
-
+ EVT SmallVT = LHS.getValueType();
+
// To determine if the result overflowed in a larger type, we extend the input
// to the larger type, do the multiply, then check the high bits of the result
// to see if the overflow happened.
@@ -568,26 +567,22 @@
LHS = ZExtPromotedInteger(LHS);
RHS = ZExtPromotedInteger(RHS);
}
-
SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
-
-
- // For an unsigned overflow, we check to see if the high part is != 0;
+
+ // Overflow occurred iff the high part of the result does not zero/sign-extend
+ // the low part.
SDValue Overflow;
if (N->getOpcode() == ISD::UMULO) {
+ // Unsigned overflow occurred iff the high part is non-zero.
SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
- DAG.getIntPtrConstant(SmallSize));
- // Overflowed if and only if this is not equal to Res.
+ DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
} else {
- // Signed multiply overflowed if the high part is not 0 and not -1.
- SDValue Hi = DAG.getNode(ISD::SRA, DL, Mul.getValueType(), Mul,
- DAG.getIntPtrConstant(SmallSize));
- Hi = DAG.getNode(ISD::ADD, DL, Hi.getValueType(), Hi,
- DAG.getConstant(1, Hi.getValueType()));
- Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
- DAG.getConstant(1, Hi.getValueType()), ISD::SETUGT);
+ // Signed overflow occurred iff the high part does not sign extend the low.
+ SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
+ Mul, DAG.getValueType(SmallVT));
+ Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
}
// Use the calculated overflow everywhere.
@@ -595,7 +590,6 @@
return Mul;
}
-
SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
// Zero extend the input.
SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
More information about the llvm-commits
mailing list