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) {