Mercurial > hg > truffle
comparison src/share/vm/opto/divnode.cpp @ 131:6e825ad773c6
6695288: runThese tests expr30303 and drem00301m1 fail when compiled code executes without deopt
Summary: rework Value method for ModD and ModF, to DTRT for infinities
Reviewed-by: sgoldman, kvn, rasbold
author | jrose |
---|---|
date | Tue, 29 Apr 2008 19:40:51 -0700 |
parents | a61af66fc99e |
children | f3de1255b035 |
comparison
equal
deleted
inserted
replaced
130:3e2d987e2e68 | 131:6e825ad773c6 |
---|---|
419 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) | 419 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) |
420 return bot; | 420 return bot; |
421 | 421 |
422 // x/x == 1, we ignore 0/0. | 422 // x/x == 1, we ignore 0/0. |
423 // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) | 423 // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) |
424 // does not work for variables because of NaN's | 424 // Does not work for variables because of NaN's |
425 if( phase->eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) | 425 if( phase->eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) |
426 if (!g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) // could be negative ZERO or NaN | 426 if (!g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) // could be negative ZERO or NaN |
427 return TypeF::ONE; | 427 return TypeF::ONE; |
428 | 428 |
429 if( t2 == TypeF::ONE ) | 429 if( t2 == TypeF::ONE ) |
489 } | 489 } |
490 | 490 |
491 //============================================================================= | 491 //============================================================================= |
492 //------------------------------Value------------------------------------------ | 492 //------------------------------Value------------------------------------------ |
493 // An DivDNode divides its inputs. The third input is a Control input, used to | 493 // An DivDNode divides its inputs. The third input is a Control input, used to |
494 // prvent hoisting the divide above an unsafe test. | 494 // prevent hoisting the divide above an unsafe test. |
495 const Type *DivDNode::Value( PhaseTransform *phase ) const { | 495 const Type *DivDNode::Value( PhaseTransform *phase ) const { |
496 // Either input is TOP ==> the result is TOP | 496 // Either input is TOP ==> the result is TOP |
497 const Type *t1 = phase->type( in(1) ); | 497 const Type *t1 = phase->type( in(1) ); |
498 const Type *t2 = phase->type( in(2) ); | 498 const Type *t2 = phase->type( in(2) ); |
499 if( t1 == Type::TOP ) return Type::TOP; | 499 if( t1 == Type::TOP ) return Type::TOP; |
870 const Type *bot = bottom_type(); | 870 const Type *bot = bottom_type(); |
871 if( (t1 == bot) || (t2 == bot) || | 871 if( (t1 == bot) || (t2 == bot) || |
872 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) | 872 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) |
873 return bot; | 873 return bot; |
874 | 874 |
875 // If either number is not a constant, we know nothing. | |
876 if ((t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon)) { | |
877 return Type::FLOAT; // note: x%x can be either NaN or 0 | |
878 } | |
879 | |
880 float f1 = t1->getf(); | |
881 float f2 = t2->getf(); | |
882 jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1 | |
883 jint x2 = jint_cast(f2); | |
884 | |
875 // If either is a NaN, return an input NaN | 885 // If either is a NaN, return an input NaN |
876 if( g_isnan(t1->getf()) ) return t1; | 886 if (g_isnan(f1)) return t1; |
877 if( g_isnan(t2->getf()) ) return t2; | 887 if (g_isnan(f2)) return t2; |
878 | 888 |
879 // It is not worth trying to constant fold this stuff! | 889 // If an operand is infinity or the divisor is +/- zero, punt. |
880 return Type::FLOAT; | 890 if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) |
881 | |
882 /* | |
883 // If dividend is infinity or divisor is zero, or both, the result is NaN | |
884 if( !g_isfinite(t1->getf()) || ((t2->getf() == 0.0) || (jint_cast(t2->getf()) == 0x80000000)) ) | |
885 | |
886 // X MOD infinity = X | |
887 if( !g_isfinite(t2->getf()) && !g_isnan(t2->getf()) ) return t1; | |
888 // 0 MOD finite = dividend (positive or negative zero) | |
889 // Not valid for: NaN MOD any; any MOD nan; 0 MOD 0; or for 0 MOD NaN | |
890 // NaNs are handled previously. | |
891 if( !(t2->getf() == 0.0) && !((int)t2->getf() == 0x80000000)) { | |
892 if (((t1->getf() == 0.0) || ((int)t1->getf() == 0x80000000)) && g_isfinite(t2->getf()) ) { | |
893 return t1; | |
894 } | |
895 } | |
896 // X MOD X is 0 | |
897 // Does not work for variables because of NaN's | |
898 if( phase->eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) | |
899 if (!g_isnan(t1->getf()) && (t1->getf() != 0.0) && ((int)t1->getf() != 0x80000000)) { | |
900 if(t1->getf() < 0.0) { | |
901 float result = jfloat_cast(0x80000000); | |
902 return TypeF::make( result ); | |
903 } | |
904 else | |
905 return TypeF::ZERO; | |
906 } | |
907 | |
908 // If both numbers are not constants, we know nothing. | |
909 if( (t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon) ) | |
910 return Type::FLOAT; | 891 return Type::FLOAT; |
911 | 892 |
912 // We must be modulo'ing 2 float constants. | 893 // We must be modulo'ing 2 float constants. |
913 // Make sure that the sign of the fmod is equal to the sign of the dividend | 894 // Make sure that the sign of the fmod is equal to the sign of the dividend |
914 float result = (float)fmod( t1->getf(), t2->getf() ); | 895 jint xr = jint_cast(fmod(f1, f2)); |
915 float dividend = t1->getf(); | 896 if ((x1 ^ xr) < 0) { |
916 if( (dividend < 0.0) || ((int)dividend == 0x80000000) ) { | 897 xr ^= min_jint; |
917 if( result > 0.0 ) | 898 } |
918 result = 0.0 - result; | 899 |
919 else if( result == 0.0 ) { | 900 return TypeF::make(jfloat_cast(xr)); |
920 result = jfloat_cast(0x80000000); | |
921 } | |
922 } | |
923 return TypeF::make( result ); | |
924 */ | |
925 } | 901 } |
926 | 902 |
927 | 903 |
928 //============================================================================= | 904 //============================================================================= |
929 //------------------------------Value------------------------------------------ | 905 //------------------------------Value------------------------------------------ |
938 const Type *bot = bottom_type(); | 914 const Type *bot = bottom_type(); |
939 if( (t1 == bot) || (t2 == bot) || | 915 if( (t1 == bot) || (t2 == bot) || |
940 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) | 916 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) |
941 return bot; | 917 return bot; |
942 | 918 |
919 // If either number is not a constant, we know nothing. | |
920 if ((t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon)) { | |
921 return Type::DOUBLE; // note: x%x can be either NaN or 0 | |
922 } | |
923 | |
924 double f1 = t1->getd(); | |
925 double f2 = t2->getd(); | |
926 jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1 | |
927 jlong x2 = jlong_cast(f2); | |
928 | |
943 // If either is a NaN, return an input NaN | 929 // If either is a NaN, return an input NaN |
944 if( g_isnan(t1->getd()) ) return t1; | 930 if (g_isnan(f1)) return t1; |
945 if( g_isnan(t2->getd()) ) return t2; | 931 if (g_isnan(f2)) return t2; |
946 // X MOD infinity = X | 932 |
947 if( !g_isfinite(t2->getd())) return t1; | 933 // If an operand is infinity or the divisor is +/- zero, punt. |
948 // 0 MOD finite = dividend (positive or negative zero) | 934 if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) |
949 // Not valid for: NaN MOD any; any MOD nan; 0 MOD 0; or for 0 MOD NaN | |
950 // NaNs are handled previously. | |
951 if( !(t2->getd() == 0.0) ) { | |
952 if( t1->getd() == 0.0 && g_isfinite(t2->getd()) ) { | |
953 return t1; | |
954 } | |
955 } | |
956 | |
957 // X MOD X is 0 | |
958 // does not work for variables because of NaN's | |
959 if( phase->eqv( in(1), in(2) ) && t1->base() == Type::DoubleCon ) | |
960 if (!g_isnan(t1->getd()) && t1->getd() != 0.0) | |
961 return TypeD::ZERO; | |
962 | |
963 | |
964 // If both numbers are not constants, we know nothing. | |
965 if( (t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon) ) | |
966 return Type::DOUBLE; | 935 return Type::DOUBLE; |
967 | 936 |
968 // We must be modulo'ing 2 double constants. | 937 // We must be modulo'ing 2 double constants. |
969 return TypeD::make( fmod( t1->getd(), t2->getd() ) ); | 938 // Make sure that the sign of the fmod is equal to the sign of the dividend |
939 jlong xr = jlong_cast(fmod(f1, f2)); | |
940 if ((x1 ^ xr) < 0) { | |
941 xr ^= min_jlong; | |
942 } | |
943 | |
944 return TypeD::make(jdouble_cast(xr)); | |
970 } | 945 } |
971 | 946 |
972 //============================================================================= | 947 //============================================================================= |
973 | 948 |
974 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) { | 949 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) { |