@@ -51,36 +51,52 @@ public CopySignNode(ValueNode magnitude, ValueNode sign) {
5151 super (TYPE , computeStamp (magnitude .stamp (NodeView .DEFAULT ), sign .stamp (NodeView .DEFAULT )), magnitude , sign );
5252 }
5353
54- public static Stamp computeStamp (Stamp stampX , Stamp stampY ) {
55- FloatStamp floatStampX = (FloatStamp ) stampX ;
56- FloatStamp floatStampY = (FloatStamp ) stampY ;
57- if (floatStampX .isNaN ()) {
58- return stampX ;
54+ public static Stamp computeStamp (Stamp magnitude , Stamp sign ) {
55+ FloatStamp magnitudeStamp = (FloatStamp ) magnitude ;
56+ FloatStamp signStamp = (FloatStamp ) sign ;
57+ if (magnitudeStamp .isNaN ()) {
58+ return magnitude ;
5959 }
60- if (floatStampY .isNonNaN ()) {
61- if (floatStampY .lowerBound () > 0 ) {
62- if (floatStampX .lowerBound () > 0 ) {
63- return floatStampX ;
60+ if (signStamp .isNonNaN ()) {
61+ if (signStamp .lowerBound () > 0 ) {
62+ // the end result will be non-negative
63+ if (magnitudeStamp .lowerBound () > 0 ) {
64+ // We know the entire range is above 0: leave it unchanged.
65+ return magnitudeStamp ;
6466 }
65- if (floatStampX .upperBound () < 0 ) {
66- return new FloatStamp (floatStampX .getBits (), -floatStampX .upperBound (), -floatStampX .lowerBound (), floatStampX .isNonNaN ());
67+ if (magnitudeStamp .upperBound () < 0 ) {
68+ // We know that the entire range is below 0
69+ // flip [lower, upper] to [-upper, -lower]
70+ return new FloatStamp (magnitudeStamp .getBits (), -magnitudeStamp .upperBound (), -magnitudeStamp .lowerBound (), magnitudeStamp .isNonNaN ());
6771 }
68- return new FloatStamp (floatStampX .getBits (), Math .min (-floatStampX .lowerBound (), floatStampX .upperBound ()),
69- Math .max (-floatStampX .lowerBound (), floatStampX .upperBound ()), floatStampX .isNonNaN ());
72+ // We know lowerBound <= 0 and upperBound >= 0:
73+ // the new range is [0, Math.max(-lower, upper)]
74+ return new FloatStamp (magnitudeStamp .getBits (), 0 ,
75+ Math .max (-magnitudeStamp .lowerBound (), magnitudeStamp .upperBound ()), magnitudeStamp .isNonNaN ());
7076 }
71- if (floatStampY .upperBound () < 0 ) {
72- if (floatStampX .upperBound () < 0 ) {
73- return floatStampX ;
77+ if (signStamp .upperBound () < 0 ) {
78+ // the result will be non-positive
79+ if (magnitudeStamp .upperBound () < 0 ) {
80+ // We know the entire range is below 0: leave it unchanged.
81+ return magnitudeStamp ;
7482 }
75- if (floatStampX .lowerBound () > 0 ) {
76- return new FloatStamp (floatStampX .getBits (), -floatStampX .upperBound (), -floatStampX .lowerBound (), floatStampX .isNonNaN ());
83+ if (magnitudeStamp .lowerBound () > 0 ) {
84+ // We know that the entire range is above 0
85+ // flip [lower, upper] to [-upper,-lower]
86+ return new FloatStamp (magnitudeStamp .getBits (), -magnitudeStamp .upperBound (), -magnitudeStamp .lowerBound (), magnitudeStamp .isNonNaN ());
7787 }
78- return new FloatStamp (floatStampX .getBits (), Math .min (floatStampX .lowerBound (), -floatStampX .upperBound ()),
79- Math .max (floatStampX .lowerBound (), -floatStampX .upperBound ()), floatStampX .isNonNaN ());
88+ // We know lowerBound <= 0 and upperBound >= 0
89+ // the new range is [Math.min(lower, -upper), 0]
90+ return new FloatStamp (magnitudeStamp .getBits (), Math .min (magnitudeStamp .lowerBound (), -magnitudeStamp .upperBound ()),
91+ 0 , magnitudeStamp .isNonNaN ());
8092 }
8193 }
82- return new FloatStamp (floatStampX .getBits (), Math .min (floatStampX .lowerBound (), -floatStampX .upperBound ()), Math .max (-floatStampX .lowerBound (), floatStampX .upperBound ()),
83- floatStampX .isNonNaN ());
94+ /*
95+ * We have no information on whether the range will be flipped or not. Hence, we have to
96+ * expand the result to be the union of [lower, upper] and [-upper, -lower].
97+ */
98+ return new FloatStamp (magnitudeStamp .getBits (), Math .min (magnitudeStamp .lowerBound (), -magnitudeStamp .upperBound ()), Math .max (-magnitudeStamp .lowerBound (), magnitudeStamp .upperBound ()),
99+ magnitudeStamp .isNonNaN ());
84100 }
85101
86102 @ Override
0 commit comments