forked from OSchip/llvm-project
constant fold bits_convert in getNode and in the dag combiner for fp<->int
conversions. This allows V8 to compiles this: void %test() { call float %test2( float 1.000000e+00, float 2.000000e+00, double 3.000000e+00, double* null ) ret void } into: test: save -96, %o6, %o6 sethi 0, %o3 sethi 1049088, %o2 sethi 1048576, %o1 sethi1040384
, %o0 or %g0, %o3, %o4 call test2 nop restore %g0, %g0, %g0 retl nop instead of: test: save -112, %o6, %o6 sethi 0, %o4 sethi 1049088, %l0 st %o4, [%i6+-12] st %l0, [%i6+-16] ld [%i6+-12], %o3 ld [%i6+-16], %o2 sethi 1048576, %o1 sethi1040384
, %o0 call test2 nop restore %g0, %g0, %g0 retl nop llvm-svn: 24980
This commit is contained in:
parent
30107e65c8
commit
a187460552
|
@ -151,6 +151,7 @@ namespace {
|
|||
SDOperand visitZERO_EXTEND(SDNode *N);
|
||||
SDOperand visitSIGN_EXTEND_INREG(SDNode *N);
|
||||
SDOperand visitTRUNCATE(SDNode *N);
|
||||
SDOperand visitBIT_CONVERT(SDNode *N);
|
||||
|
||||
SDOperand visitFADD(SDNode *N);
|
||||
SDOperand visitFSUB(SDNode *N);
|
||||
|
@ -609,6 +610,7 @@ SDOperand DAGCombiner::visit(SDNode *N) {
|
|||
case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N);
|
||||
case ISD::SIGN_EXTEND_INREG: return visitSIGN_EXTEND_INREG(N);
|
||||
case ISD::TRUNCATE: return visitTRUNCATE(N);
|
||||
case ISD::BIT_CONVERT: return visitBIT_CONVERT(N);
|
||||
case ISD::FADD: return visitFADD(N);
|
||||
case ISD::FSUB: return visitFSUB(N);
|
||||
case ISD::FMUL: return visitFMUL(N);
|
||||
|
@ -1745,6 +1747,19 @@ SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) {
|
|||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitBIT_CONVERT(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
MVT::ValueType VT = N->getValueType(0);
|
||||
|
||||
// If the input is a constant, let getNode() fold it.
|
||||
if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
|
||||
SDOperand Res = DAG.getNode(ISD::BIT_CONVERT, VT, N0);
|
||||
if (Res.Val != N) return Res;
|
||||
}
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitFADD(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
|
|
|
@ -828,6 +828,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
|
|||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand Operand) {
|
||||
// Constant fold unary operations with an integer constant operand.
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.Val)) {
|
||||
uint64_t Val = C->getValue();
|
||||
switch (Opcode) {
|
||||
|
@ -838,13 +839,25 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
|||
case ISD::TRUNCATE: return getConstant(Val, VT);
|
||||
case ISD::SINT_TO_FP: return getConstantFP(C->getSignExtended(), VT);
|
||||
case ISD::UINT_TO_FP: return getConstantFP(C->getValue(), VT);
|
||||
case ISD::BIT_CONVERT:
|
||||
if (VT == MVT::f32) {
|
||||
assert(C->getValueType(0) == MVT::i32 && "Invalid bit_convert!");
|
||||
return getConstantFP(BitsToFloat(Val), VT);
|
||||
} else if (VT == MVT::f64) {
|
||||
assert(C->getValueType(0) == MVT::i64 && "Invalid bit_convert!");
|
||||
return getConstantFP(BitsToDouble(Val), VT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Constant fold unary operations with an floating point constant operand.
|
||||
if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.Val))
|
||||
switch (Opcode) {
|
||||
case ISD::FNEG:
|
||||
return getConstantFP(-C->getValue(), VT);
|
||||
case ISD::FABS:
|
||||
return getConstantFP(fabs(C->getValue()), VT);
|
||||
case ISD::FP_ROUND:
|
||||
case ISD::FP_EXTEND:
|
||||
return getConstantFP(C->getValue(), VT);
|
||||
|
@ -852,6 +865,15 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
|||
return getConstant((int64_t)C->getValue(), VT);
|
||||
case ISD::FP_TO_UINT:
|
||||
return getConstant((uint64_t)C->getValue(), VT);
|
||||
case ISD::BIT_CONVERT:
|
||||
if (VT == MVT::i32) {
|
||||
assert(C->getValueType(0) == MVT::f32 && "Invalid bit_convert!");
|
||||
return getConstant(FloatToBits(C->getValue()), VT);
|
||||
} else if (VT == MVT::i64) {
|
||||
assert(C->getValueType(0) == MVT::f64 && "Invalid bit_convert!");
|
||||
return getConstant(DoubleToBits(C->getValue()), VT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned OpOpcode = Operand.Val->getOpcode();
|
||||
|
|
Loading…
Reference in New Issue