aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2009-12-03 21:37:32 +0000
committerDuncan Sands <baldrick@free.fr>2009-12-03 21:37:32 +0000
commit9993b88f06fd54c0be31d35f0970ada70a4c0439 (patch)
treeb49e3cf54a01ad529102922891d25639949f0273 /lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
parentf4811a96941433fc3828869d76dfeba5ec5decd3 (diff)
Fix ExpandShiftWithUnknownAmountBit, which was completely bogus.
Pointed out by Javier Martinez (who also provided a patch). Since this logic is not used on (for example) x86, I guess nobody noticed. Tested by generating SHL, SRL, SRA on various choices of i64 for all possible shift amounts, and comparing with gcc. Since I did this on x86-32, I had to force the use of ExpandShiftWithUnknownAmountBit. What I'm saying here is that I don't have a testcase I can add to the repository. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90482 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp75
1 files changed, 38 insertions, 37 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 8ac8063be9..5599d25f6e 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1167,55 +1167,56 @@ ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
GetExpandedInteger(N->getOperand(0), InL, InH);
SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
- SDValue Amt2 = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
- SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
- Amt, NVBitsNode, ISD::SETULT);
+ SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
+ SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
+ SDValue isShort = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
+ Amt, NVBitsNode, ISD::SETULT);
- SDValue Lo1, Hi1, Lo2, Hi2;
+ SDValue LoS, HiS, LoL, HiL;
switch (N->getOpcode()) {
default: llvm_unreachable("Unknown shift");
case ISD::SHL:
- // ShAmt < NVTBits
- Lo1 = DAG.getConstant(0, NVT); // Low part is zero.
- Hi1 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
-
- // ShAmt >= NVTBits
- Lo2 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
- Hi2 = DAG.getNode(ISD::OR, dl, NVT,
+ // Short: ShAmt < NVTBits
+ LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
+ HiS = DAG.getNode(ISD::OR, dl, NVT,
DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
- DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2));
+ DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
+
+ // Long: ShAmt >= NVTBits
+ LoL = DAG.getConstant(0, NVT); // Lo part is zero.
+ HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
- Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
- Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
+ Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
return true;
case ISD::SRL:
- // ShAmt < NVTBits
- Hi1 = DAG.getConstant(0, NVT); // Hi part is zero.
- Lo1 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
-
- // ShAmt >= NVTBits
- Hi2 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
- Lo2 = DAG.getNode(ISD::OR, dl, NVT,
- DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
- DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
-
- Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
- Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
+ // Short: ShAmt < NVTBits
+ HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
+ LoS = DAG.getNode(ISD::OR, dl, NVT,
+ DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
+ DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
+
+ // Long: ShAmt >= NVTBits
+ HiL = DAG.getConstant(0, NVT); // Hi part is zero.
+ LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
+
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
+ Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
return true;
case ISD::SRA:
- // ShAmt < NVTBits
- Hi1 = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
- DAG.getConstant(NVTBits-1, ShTy));
- Lo1 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
-
- // ShAmt >= NVTBits
- Hi2 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
- Lo2 = DAG.getNode(ISD::OR, dl, NVT,
+ // Short: ShAmt < NVTBits
+ HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
+ LoS = DAG.getNode(ISD::OR, dl, NVT,
DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
- DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
+ DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
+
+ // Long: ShAmt >= NVTBits
+ HiL = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign of Hi part.
+ DAG.getConstant(NVTBits-1, ShTy));
+ LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
- Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
- Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
+ Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
+ Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
return true;
}