diff options
author | Chris Lattner <sabre@nondot.org> | 2005-12-23 05:30:37 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-12-23 05:30:37 +0000 |
commit | a18746055282076c04086559d1aa9746978ca343 (patch) | |
tree | e4e70810b0072cb9acd0675a7065a5c72900018b /llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 30107e65c827534afc316e97234410c2074eb673 (diff) | |
download | bcm5719-llvm-a18746055282076c04086559d1aa9746978ca343.tar.gz bcm5719-llvm-a18746055282076c04086559d1aa9746978ca343.zip |
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
sethi 1040384, %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
sethi 1040384, %o0
call test2
nop
restore %g0, %g0, %g0
retl
nop
llvm-svn: 24980
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ec75dfee32a..76d983f57e8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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(); |