forked from OSchip/llvm-project
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 llvm-svn: 19780
This commit is contained in:
parent
ffcb0ae329
commit
90b7c13f3a
|
@ -16,6 +16,7 @@
|
||||||
#include "llvm/GlobalValue.h"
|
#include "llvm/GlobalValue.h"
|
||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -141,6 +142,11 @@ ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
|
||||||
return ISD::CondCode(Op1 & Op2);
|
return ISD::CondCode(Op1 & Op2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TargetMachine &SelectionDAG::getTarget() const {
|
||||||
|
return TLI.getTargetMachine();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// RemoveDeadNodes - This method deletes all unreachable nodes in the
|
/// RemoveDeadNodes - This method deletes all unreachable nodes in the
|
||||||
/// SelectionDAG, including nodes (like loads) that have uses of their token
|
/// 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
|
/// 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));
|
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
|
// Simplify (X+Z) == X --> Z == 0
|
||||||
if (N1.getOperand(0) == N2)
|
if (N1.getOperand(0) == N2)
|
||||||
|
@ -446,10 +454,9 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT,
|
||||||
else {
|
else {
|
||||||
assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
|
assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
|
||||||
// (Z-X) == X --> Z == X<<1
|
// (Z-X) == X --> Z == X<<1
|
||||||
if (N2.getValueType() != MVT::i64) // FIXME: HACK HACK HACK!
|
|
||||||
return getSetCC(Cond, VT, N1.getOperand(0),
|
return getSetCC(Cond, VT, N1.getOperand(0),
|
||||||
getNode(ISD::SHL, N2.getValueType(),
|
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
|
if (N2C->isAllOnesValue()) // mul X, -1 -> 0-X
|
||||||
return getNode(ISD::SUB, VT, getConstant(0, VT), N1);
|
return getNode(ISD::SUB, VT, getConstant(0, VT), N1);
|
||||||
|
|
||||||
// FIXME: This should only be done if the target supports shift
|
// FIXME: Move this to the DAG combiner when it exists.
|
||||||
// operations.
|
|
||||||
if ((C2 & C2-1) == 0) {
|
if ((C2 & C2-1) == 0) {
|
||||||
if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK!
|
SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy());
|
||||||
SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8);
|
return getNode(ISD::SHL, VT, N1, ShAmt);
|
||||||
return getNode(ISD::SHL, VT, N1, ShAmt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::UDIV:
|
case ISD::UDIV:
|
||||||
// FIXME: This should only be done if the target supports shift
|
// FIXME: Move this to the DAG combiner when it exists.
|
||||||
// operations.
|
|
||||||
if ((C2 & C2-1) == 0 && C2) {
|
if ((C2 & C2-1) == 0 && C2) {
|
||||||
if (N1.getValueType() != MVT::i64) { // FIXME: HACK HACK HACK!
|
SDOperand ShAmt = getConstant(ExactLog2(C2), TLI.getShiftAmountTy());
|
||||||
SDOperand ShAmt = getConstant(ExactLog2(C2), MVT::i8);
|
return getNode(ISD::SRL, VT, N1, ShAmt);
|
||||||
return getNode(ISD::SRL, VT, N1, ShAmt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::SHL:
|
case ISD::SHL:
|
||||||
case ISD::SRL:
|
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:
|
case ISD::SRA:
|
||||||
if (C2 == 0) return N1;
|
if (C2 == 0) return N1;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue