diff options
author | Chris Lattner <sabre@nondot.org> | 2005-01-23 04:39:44 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-01-23 04:39:44 +0000 |
commit | b48da3953642d3d006edebd7fc6c1ca5bcfdb5cd (patch) | |
tree | 7734e8b3c9abfb00b05e7a6922d58252a186a481 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | ac9dc08c7f0ae60c125624d72c3022025d79ee9e (diff) |
Remove the 3 HACK HACK HACKs I put in before, fixing them properly with
the new TLI that is available.
Implement support for handling out of range shifts. This allows us to
compile this code (a 64-bit rotate):
unsigned long long f3(unsigned long long x) {
return (x << 32) | (x >> (64-32));
}
into this:
f3:
mov %EDX, DWORD PTR [%ESP + 4]
mov %EAX, DWORD PTR [%ESP + 8]
ret
GCC produces this:
$ gcc t.c -masm=intel -O3 -S -o - -fomit-frame-pointer
..
f3:
push %ebx
mov %ebx, DWORD PTR [%esp+12]
mov %ecx, DWORD PTR [%esp+8]
mov %eax, %ebx
mov %edx, %ecx
pop %ebx
ret
The Simple ISEL produces (eww gross):
f3:
sub %ESP, 4
mov DWORD PTR [%ESP], %ESI
mov %EDX, DWORD PTR [%ESP + 8]
mov %ECX, DWORD PTR [%ESP + 12]
mov %EAX, 0
mov %ESI, 0
or %EAX, %ECX
or %EDX, %ESI
mov %ESI, DWORD PTR [%ESP]
add %ESP, 4
ret
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19780 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index f18d06707a..a35e584b9f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -16,6 +16,7 @@ #include "llvm/GlobalValue.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetLowering.h" #include <iostream> #include <set> #include <cmath> @@ -141,6 +142,11 @@ ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2, return ISD::CondCode(Op1 & Op2); } +const TargetMachine &SelectionDAG::getTarget() const { + return TLI.getTargetMachine(); +} + + /// RemoveDeadNodes - This method deletes all unreachable nodes in the /// SelectionDAG, including nodes (like loads) that have uses of their token /// chain but no other uses and no side effect. If a node is passed in as an @@ -434,6 +440,8 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); } } + + // FIXME: move this stuff to the DAG Combiner when it exists! // Simplify (X+Z) == X --> Z == 0 if (N1.getOperand(0) == N2) @@ -446,10 +454,9 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - if (N2.getValueType() != MVT::i64) // FIXME: HACK HACK HACK! return getSetCC(Cond, VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), - N2, getConstant(1, MVT::i8))); + N2, getConstant(1, TLI.getShiftAmountTy()))); } } } @@ -652,29 +659,35 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, if (N2C->isAllOnesValue()) // mul X, -1 -> 0-X return getNode(ISD::SUB, VT, getConstant(0, VT), N1); - // FIXME: This should only be done if the target supports shift - // operations. + // FIXME: Move this to the DAG combiner when it exists. if ((C2 & C2-1) == 0) { - if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SHL, VT, N1, ShAmt); - } + SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy()); + return getNode(ISD::SHL, VT, N1, ShAmt); } break; case ISD::UDIV: - // FIXME: This should only be done if the target supports shift - // operations. + // FIXME: Move this to the DAG combiner when it exists. if ((C2 & C2-1) == 0 && C2) { - if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK! - SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8); - return getNode(ISD::SRL, VT, N1, ShAmt); - } + SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy()); + return getNode(ISD::SRL, VT, N1, ShAmt); } break; case ISD::SHL: case ISD::SRL: + // If the shift amount is bigger than the size of the data, simplify. + if (C2 >= MVT::getSizeInBits(N1.getValueType())) { + if (TLI.getShiftAmountFlavor() == TargetLowering::Mask) { + unsigned NewAmt = + C2 & ((1 << MVT::getSizeInBits(N1.getValueType()))-1); + return getNode(Opcode, VT, N1, getConstant(NewAmt,N2.getValueType())); + } else if (TLI.getShiftAmountFlavor() == TargetLowering::Extend) { + // Shifting all of the bits out? + return getConstant(0, N1.getValueType()); + } + } + // FALL THROUGH. case ISD::SRA: if (C2 == 0) return N1; break; |