mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-30 05:29:47 +00:00
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
This commit is contained in:
parent
f4811a9694
commit
9993b88f06
@ -1167,55 +1167,56 @@ ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
|
|||||||
GetExpandedInteger(N->getOperand(0), InL, InH);
|
GetExpandedInteger(N->getOperand(0), InL, InH);
|
||||||
|
|
||||||
SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
|
SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
|
||||||
SDValue Amt2 = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
|
SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
|
||||||
SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
|
SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
|
||||||
Amt, NVBitsNode, ISD::SETULT);
|
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()) {
|
switch (N->getOpcode()) {
|
||||||
default: llvm_unreachable("Unknown shift");
|
default: llvm_unreachable("Unknown shift");
|
||||||
case ISD::SHL:
|
case ISD::SHL:
|
||||||
// ShAmt < NVTBits
|
// Short: ShAmt < NVTBits
|
||||||
Lo1 = DAG.getConstant(0, NVT); // Low part is zero.
|
LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
|
||||||
Hi1 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
|
HiS = DAG.getNode(ISD::OR, dl, NVT,
|
||||||
|
|
||||||
// ShAmt >= NVTBits
|
|
||||||
Lo2 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
|
|
||||||
Hi2 = DAG.getNode(ISD::OR, dl, NVT,
|
|
||||||
DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
|
DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
|
||||||
DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2));
|
DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
|
||||||
|
|
||||||
Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
|
// Long: ShAmt >= NVTBits
|
||||||
Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
|
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, isShort, LoS, LoL);
|
||||||
|
Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
|
||||||
return true;
|
return true;
|
||||||
case ISD::SRL:
|
case ISD::SRL:
|
||||||
// ShAmt < NVTBits
|
// Short: ShAmt < NVTBits
|
||||||
Hi1 = DAG.getConstant(0, NVT); // Hi part is zero.
|
HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
|
||||||
Lo1 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
|
LoS = DAG.getNode(ISD::OR, dl, NVT,
|
||||||
|
DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
|
||||||
|
DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
|
||||||
|
|
||||||
// ShAmt >= NVTBits
|
// Long: ShAmt >= NVTBits
|
||||||
Hi2 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
|
HiL = DAG.getConstant(0, NVT); // Hi part is zero.
|
||||||
Lo2 = DAG.getNode(ISD::OR, dl, NVT,
|
LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
|
||||||
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);
|
Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
|
||||||
Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
|
Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
|
||||||
return true;
|
return true;
|
||||||
case ISD::SRA:
|
case ISD::SRA:
|
||||||
// ShAmt < NVTBits
|
// Short: ShAmt < NVTBits
|
||||||
Hi1 = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part.
|
HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
|
||||||
DAG.getConstant(NVTBits-1, ShTy));
|
LoS = DAG.getNode(ISD::OR, dl, NVT,
|
||||||
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,
|
|
||||||
DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
|
DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
|
||||||
DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
|
DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
|
||||||
|
|
||||||
Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
|
// Long: ShAmt >= NVTBits
|
||||||
Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
|
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, isShort, LoS, LoL);
|
||||||
|
Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user