summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-12-23 05:30:37 +0000
committerChris Lattner <sabre@nondot.org>2005-12-23 05:30:37 +0000
commita18746055282076c04086559d1aa9746978ca343 (patch)
treee4e70810b0072cb9acd0675a7065a5c72900018b /llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parent30107e65c827534afc316e97234410c2074eb673 (diff)
downloadbcm5719-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.cpp22
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();
OpenPOWER on IntegriCloud