Extend constant folding to float and double operations.

Change-Id: I2837064b2ceea587bc171fc520507f13355292c6
diff --git a/test/442-checker-constant-folding/smali/TestCmp.smali b/test/442-checker-constant-folding/smali/TestCmp.smali
new file mode 100644
index 0000000..df631bc
--- /dev/null
+++ b/test/442-checker-constant-folding/smali/TestCmp.smali
@@ -0,0 +1,332 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public LTestCmp;
+
+.super Ljava/lang/Object;
+
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (before)
+## CHECK-DAG:     <<Const13:j\d+>>  LongConstant 13
+## CHECK-DAG:     <<Const7:j\d+>>   LongConstant 7
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const13>>,<<Const7>>]
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (after)
+## CHECK-DAG:                       LongConstant 13
+## CHECK-DAG:                       LongConstant 7
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:                       Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLongConstants()I
+   .registers 5
+   const-wide v1, 13
+   const-wide v3, 7
+   cmp-long v0, v1, v3
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (before)
+## CHECK-DAG:     <<Const11:f\d+>>  FloatConstant 11
+## CHECK-DAG:     <<Const22:f\d+>>  FloatConstant 22
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const11>>,<<Const22>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 11
+## CHECK-DAG:                       FloatConstant 22
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtFloatConstants()I
+   .registers 3
+   const v1, 11.f
+   const v2, 22.f
+   cmpg-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (before)
+## CHECK-DAG:     <<Const33:f\d+>>  FloatConstant 33
+## CHECK-DAG:     <<Const44:f\d+>>  FloatConstant 44
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const33>>,<<Const44>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 33
+## CHECK-DAG:                       FloatConstant 44
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtFloatConstants()I
+   .registers 3
+   const v1, 33.f
+   const v2, 44.f
+   cmpl-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (before)
+## CHECK-DAG:     <<Const55:d\d+>>  DoubleConstant 55
+## CHECK-DAG:     <<Const66:d\d+>>  DoubleConstant 66
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const55>>,<<Const66>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 55
+## CHECK-DAG:                       DoubleConstant 66
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtDoubleConstants()I
+   .registers 5
+   const-wide v1, 55.
+   const-wide v3, 66.
+   cmpg-double v0, v1, v3
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (before)
+## CHECK-DAG:     <<Const77:d\d+>>  DoubleConstant 77
+## CHECK-DAG:     <<Const88:d\d+>>  DoubleConstant 88
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const77>>,<<Const88>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 77
+## CHECK-DAG:                       DoubleConstant 88
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtDoubleConstants()I
+   .registers 5
+   const-wide v1, 77.
+   const-wide v3, 88.
+   cmpl-double v0, v1, v3
+   return v0
+.end method
+
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (before)
+## CHECK-DAG:     <<Const100:j\d+>> LongConstant 100
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const100>>,<<Const100>>]
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (after)
+## CHECK-DAG:                       LongConstant 100
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:                       Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLongSameConstant()I
+   .registers 5
+   const-wide v1, 100
+   const-wide v3, 100
+   cmp-long v0, v1, v3
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (before)
+## CHECK-DAG:     <<Const200:f\d+>> FloatConstant 200
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const200>>,<<Const200>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 200
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:                       Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtFloatSameConstant()I
+   .registers 3
+   const v1, 200.f
+   const v2, 200.f
+   cmpg-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (before)
+## CHECK-DAG:     <<Const300:f\d+>> FloatConstant 300
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const300>>,<<Const300>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 300
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:                       Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtFloatSameConstant()I
+   .registers 3
+   const v1, 300.f
+   const v2, 300.f
+   cmpl-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (before)
+## CHECK-DAG:     <<Const400:d\d+>> DoubleConstant 400
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const400>>,<<Const400>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 400
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:                       Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtDoubleSameConstant()I
+   .registers 5
+   const-wide v1, 400.
+   const-wide v3, 400.
+   cmpg-double v0, v1, v3
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (before)
+## CHECK-DAG:     <<Const500:d\d+>> DoubleConstant 500
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const500>>,<<Const500>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 500
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:                       Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtDoubleSameConstant()I
+   .registers 5
+   const-wide v1, 500.
+   const-wide v3, 500.
+   cmpl-double v0, v1, v3
+   return v0
+.end method
+
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (before)
+## CHECK-DAG:     <<Const44:f\d+>>  FloatConstant 44
+## CHECK-DAG:     <<ConstNan:f\d+>> FloatConstant nan
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const44>>,<<ConstNan>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 44
+## CHECK-DAG:                       FloatConstant nan
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:                       Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtFloatConstantWithNaN()I
+   .registers 3
+   const v1, 44.f
+   const v2, NaNf
+   cmpg-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (before)
+## CHECK-DAG:     <<Const44:f\d+>>  FloatConstant 44
+## CHECK-DAG:     <<ConstNan:f\d+>> FloatConstant nan
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const44>>,<<ConstNan>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (after)
+## CHECK-DAG:                       FloatConstant 44
+## CHECK-DAG:                       FloatConstant nan
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtFloatConstantWithNaN()I
+   .registers 3
+   const v1, 44.f
+   const v2, NaNf
+   cmpl-float v0, v1, v2
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (before)
+## CHECK-DAG:     <<Const45:d\d+>>  DoubleConstant 45
+## CHECK-DAG:     <<ConstNan:d\d+>> DoubleConstant nan
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const45>>,<<ConstNan>>] bias:gt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 45
+## CHECK-DAG:                       DoubleConstant nan
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:                       Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpGtDoubleConstantWithNaN()I
+   .registers 5
+   const-wide v1, 45.
+   const-wide v3, NaN
+   cmpg-double v0, v1, v3
+   return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (before)
+## CHECK-DAG:     <<Const46:d\d+>>  DoubleConstant 46
+## CHECK-DAG:     <<ConstNan:d\d+>> DoubleConstant nan
+## CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Const46>>,<<ConstNan>>] bias:lt
+## CHECK-DAG:                       Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-DAG:                       DoubleConstant 46
+## CHECK-DAG:                       DoubleConstant nan
+## CHECK-DAG:     <<ConstM1:i\d+>>  IntConstant -1
+## CHECK-DAG:                       Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-NOT:                       Compare
+
+.method public static $opt$CmpLtDoubleConstantWithNaN()I
+   .registers 5
+   const-wide v1, 46.
+   const-wide v3, NaN
+   cmpl-double v0, v1, v3
+   return v0
+.end method
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 5479818..93fe397 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
+import java.lang.reflect.Method;
+
 public class Main {
 
+  // Workaround for b/18051191.
+  class InnerClass {}
+
   public static void assertFalse(boolean condition) {
     if (condition) {
       throw new Error();
@@ -47,6 +52,68 @@
   }
 
 
+  // Wrappers around methods located in file TestCmp.smali.
+
+  public int smaliCmpLongConstants() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLongConstants");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpGtFloatConstants() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtFloatConstants");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtFloatConstants() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtFloatConstants");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpGtDoubleConstants() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtDoubleConstants");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtDoubleConstants() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtDoubleConstants");
+    return (Integer)m.invoke(null);
+  }
+
+  public int smaliCmpLongSameConstant() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLongSameConstant");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpGtFloatSameConstant() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtFloatSameConstant");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtFloatSameConstant() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtFloatSameConstant");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpGtDoubleSameConstant() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtDoubleSameConstant");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtDoubleSameConstant() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtDoubleSameConstant");
+    return (Integer)m.invoke(null);
+  }
+
+  public int smaliCmpGtFloatConstantWithNaN() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtFloatConstantWithNaN");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtFloatConstantWithNaN() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtFloatConstantWithNaN");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpGtDoubleConstantWithNaN() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpGtDoubleConstantWithNaN");
+    return (Integer)m.invoke(null);
+  }
+  public int smaliCmpLtDoubleConstantWithNaN() throws Exception {
+    Method m = testCmp.getMethod("$opt$CmpLtDoubleConstantWithNaN");
+    return (Integer)m.invoke(null);
+  }
+
+
   /**
    * Exercise constant folding on negation.
    */
@@ -89,6 +156,44 @@
     return y;
   }
 
+  /// CHECK-START: float Main.FloatNegation() constant_folding (before)
+  /// CHECK-DAG:     <<Const42:f\d+>>  FloatConstant 42
+  /// CHECK-DAG:     <<Neg:f\d+>>      Neg [<<Const42>>]
+  /// CHECK-DAG:                       Return [<<Neg>>]
+
+  /// CHECK-START: float Main.FloatNegation() constant_folding (after)
+  /// CHECK-DAG:     <<ConstN42:f\d+>> FloatConstant -42
+  /// CHECK-DAG:                       Return [<<ConstN42>>]
+
+  /// CHECK-START: float Main.FloatNegation() constant_folding (after)
+  /// CHECK-NOT:                       Neg
+
+  public static float FloatNegation() {
+    float x, y;
+    x = 42F;
+    y = -x;
+    return y;
+  }
+
+  /// CHECK-START: double Main.DoubleNegation() constant_folding (before)
+  /// CHECK-DAG:     <<Const42:d\d+>>  DoubleConstant 42
+  /// CHECK-DAG:     <<Neg:d\d+>>      Neg [<<Const42>>]
+  /// CHECK-DAG:                       Return [<<Neg>>]
+
+  /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
+  /// CHECK-DAG:     <<ConstN42:d\d+>> DoubleConstant -42
+  /// CHECK-DAG:                       Return [<<ConstN42>>]
+
+  /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
+  /// CHECK-NOT:                       Neg
+
+  public static double DoubleNegation() {
+    double x, y;
+    x = 42D;
+    y = -x;
+    return y;
+  }
+
 
   /**
    * Exercise constant folding on addition.
@@ -166,6 +271,48 @@
     return c;
   }
 
+  /// CHECK-START: float Main.FloatAddition() constant_folding (before)
+  /// CHECK-DAG:     <<Const1:f\d+>>  FloatConstant 1
+  /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
+  /// CHECK-DAG:     <<Add:f\d+>>     Add [<<Const1>>,<<Const2>>]
+  /// CHECK-DAG:                      Return [<<Add>>]
+
+  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+  /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
+  /// CHECK-DAG:                      Return [<<Const3>>]
+
+  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+  /// CHECK-NOT:                      Add
+
+  public static float FloatAddition() {
+    float a, b, c;
+    a = 1F;
+    b = 2F;
+    c = a + b;
+    return c;
+  }
+
+  /// CHECK-START: double Main.DoubleAddition() constant_folding (before)
+  /// CHECK-DAG:     <<Const1:d\d+>>  DoubleConstant 1
+  /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
+  /// CHECK-DAG:     <<Add:d\d+>>     Add [<<Const1>>,<<Const2>>]
+  /// CHECK-DAG:                      Return [<<Add>>]
+
+  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+  /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
+  /// CHECK-DAG:                      Return [<<Const3>>]
+
+  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+  /// CHECK-NOT:                      Add
+
+  public static double DoubleAddition() {
+    double a, b, c;
+    a = 1D;
+    b = 2D;
+    c = a + b;
+    return c;
+  }
+
 
   /**
    * Exercise constant folding on subtraction.
@@ -213,6 +360,48 @@
     return c;
   }
 
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding (before)
+  /// CHECK-DAG:     <<Const6:f\d+>>  FloatConstant 6
+  /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
+  /// CHECK-DAG:     <<Sub:f\d+>>     Sub [<<Const6>>,<<Const2>>]
+  /// CHECK-DAG:                      Return [<<Sub>>]
+
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+  /// CHECK-DAG:     <<Const4:f\d+>>  FloatConstant 4
+  /// CHECK-DAG:                      Return [<<Const4>>]
+
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+  /// CHECK-NOT:                      Sub
+
+  public static float FloatSubtraction() {
+    float a, b, c;
+    a = 6F;
+    b = 2F;
+    c = a - b;
+    return c;
+  }
+
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (before)
+  /// CHECK-DAG:     <<Const6:d\d+>>  DoubleConstant 6
+  /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
+  /// CHECK-DAG:     <<Sub:d\d+>>     Sub [<<Const6>>,<<Const2>>]
+  /// CHECK-DAG:                      Return [<<Sub>>]
+
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+  /// CHECK-DAG:     <<Const4:d\d+>>  DoubleConstant 4
+  /// CHECK-DAG:                      Return [<<Const4>>]
+
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+  /// CHECK-NOT:                      Sub
+
+  public static double DoubleSubtraction() {
+    double a, b, c;
+    a = 6D;
+    b = 2D;
+    c = a - b;
+    return c;
+  }
+
 
   /**
    * Exercise constant folding on multiplication.
@@ -260,6 +449,48 @@
     return c;
   }
 
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding (before)
+  /// CHECK-DAG:     <<Const7:f\d+>>  FloatConstant 7
+  /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
+  /// CHECK-DAG:     <<Mul:f\d+>>     Mul [<<Const7>>,<<Const3>>]
+  /// CHECK-DAG:                      Return [<<Mul>>]
+
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+  /// CHECK-DAG:     <<Const21:f\d+>> FloatConstant 21
+  /// CHECK-DAG:                      Return [<<Const21>>]
+
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+  /// CHECK-NOT:                      Mul
+
+  public static float FloatMultiplication() {
+    float a, b, c;
+    a = 7F;
+    b = 3F;
+    c = a * b;
+    return c;
+  }
+
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (before)
+  /// CHECK-DAG:     <<Const7:d\d+>>  DoubleConstant 7
+  /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
+  /// CHECK-DAG:     <<Mul:d\d+>>     Mul [<<Const7>>,<<Const3>>]
+  /// CHECK-DAG:                      Return [<<Mul>>]
+
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+  /// CHECK-DAG:     <<Const21:d\d+>> DoubleConstant 21
+  /// CHECK-DAG:                      Return [<<Const21>>]
+
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+  /// CHECK-NOT:                      Mul
+
+  public static double DoubleMultiplication() {
+    double a, b, c;
+    a = 7D;
+    b = 3D;
+    c = a * b;
+    return c;
+  }
+
 
   /**
    * Exercise constant folding on division.
@@ -311,6 +542,48 @@
     return c;
   }
 
+  /// CHECK-START: float Main.FloatDivision() constant_folding (before)
+  /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
+  /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
+  /// CHECK-DAG:     <<Div:f\d+>>      Div [<<Const8>>,<<Const2P5>>]
+  /// CHECK-DAG:                       Return [<<Div>>]
+
+  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+  /// CHECK-DAG:     <<Const3P2:f\d+>> FloatConstant 3.2
+  /// CHECK-DAG:                       Return [<<Const3P2>>]
+
+  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+  /// CHECK-NOT:                       Div
+
+  public static float FloatDivision() {
+    float a, b, c;
+    a = 8F;
+    b = 2.5F;
+    c = a / b;
+    return c;
+  }
+
+  /// CHECK-START: double Main.DoubleDivision() constant_folding (before)
+  /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
+  /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
+  /// CHECK-DAG:     <<Div:d\d+>>      Div [<<Const8>>,<<Const2P5>>]
+  /// CHECK-DAG:                       Return [<<Div>>]
+
+  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+  /// CHECK-DAG:     <<Const3P2:d\d+>> DoubleConstant 3.2
+  /// CHECK-DAG:                       Return [<<Const3P2>>]
+
+  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+  /// CHECK-NOT:                       Div
+
+  public static double DoubleDivision() {
+    double a, b, c;
+    a = 8D;
+    b = 2.5D;
+    c = a / b;
+    return c;
+  }
+
 
   /**
    * Exercise constant folding on remainder.
@@ -362,6 +635,48 @@
     return c;
   }
 
+  /// CHECK-START: float Main.FloatRemainder() constant_folding (before)
+  /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
+  /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
+  /// CHECK-DAG:     <<Rem:f\d+>>      Rem [<<Const8>>,<<Const2P5>>]
+  /// CHECK-DAG:                       Return [<<Rem>>]
+
+  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+  /// CHECK-DAG:     <<Const0P5:f\d+>> FloatConstant 0.5
+  /// CHECK-DAG:                       Return [<<Const0P5>>]
+
+  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+  /// CHECK-NOT:                       Rem
+
+  public static float FloatRemainder() {
+    float a, b, c;
+    a = 8F;
+    b = 2.5F;
+    c = a % b;
+    return c;
+  }
+
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding (before)
+  /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
+  /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
+  /// CHECK-DAG:     <<Rem:d\d+>>      Rem [<<Const8>>,<<Const2P5>>]
+  /// CHECK-DAG:                       Return [<<Rem>>]
+
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+  /// CHECK-DAG:     <<Const0P5:d\d+>> DoubleConstant 0.5
+  /// CHECK-DAG:                       Return [<<Const0P5>>]
+
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+  /// CHECK-NOT:                       Rem
+
+  public static double DoubleRemainder() {
+    double a, b, c;
+    a = 8D;
+    b = 2.5D;
+    c = a % b;
+    return c;
+  }
+
 
   /**
    * Exercise constant folding on left shift.
@@ -1197,25 +1512,37 @@
   }
 
 
-  public static void main(String[] args) {
+  public static void main(String[] args) throws Exception {
     assertIntEquals(-42, IntNegation());
     assertLongEquals(-42L, LongNegation());
+    assertFloatEquals(-42F, FloatNegation());
+    assertDoubleEquals(-42D, DoubleNegation());
 
     assertIntEquals(3, IntAddition1());
     assertIntEquals(14, IntAddition2());
     assertLongEquals(3L, LongAddition());
+    assertFloatEquals(3F, FloatAddition());
+    assertDoubleEquals(3D, DoubleAddition());
 
     assertIntEquals(4, IntSubtraction());
     assertLongEquals(4L, LongSubtraction());
+    assertFloatEquals(4F, FloatSubtraction());
+    assertDoubleEquals(4D, DoubleSubtraction());
 
     assertIntEquals(21, IntMultiplication());
     assertLongEquals(21L, LongMultiplication());
+    assertFloatEquals(21F, FloatMultiplication());
+    assertDoubleEquals(21D, DoubleMultiplication());
 
     assertIntEquals(2, IntDivision());
     assertLongEquals(2L, LongDivision());
+    assertFloatEquals(3.2F, FloatDivision());
+    assertDoubleEquals(3.2D, DoubleDivision());
 
     assertIntEquals(2, IntRemainder());
     assertLongEquals(2L, LongRemainder());
+    assertFloatEquals(0.5F, FloatRemainder());
+    assertDoubleEquals(0.5D, DoubleRemainder());
 
     assertIntEquals(4, ShlIntLong());
     assertLongEquals(12L, ShlLongInt());
@@ -1259,6 +1586,24 @@
     assertFalse(CmpFloatGreaterThanNaN(arbitrary));
     assertFalse(CmpDoubleLessThanNaN(arbitrary));
 
+    Main main = new Main();
+    assertIntEquals(1, main.smaliCmpLongConstants());
+    assertIntEquals(-1, main.smaliCmpGtFloatConstants());
+    assertIntEquals(-1, main.smaliCmpLtFloatConstants());
+    assertIntEquals(-1, main.smaliCmpGtDoubleConstants());
+    assertIntEquals(-1, main.smaliCmpLtDoubleConstants());
+
+    assertIntEquals(0, main.smaliCmpLongSameConstant());
+    assertIntEquals(0, main.smaliCmpGtFloatSameConstant());
+    assertIntEquals(0, main.smaliCmpLtFloatSameConstant());
+    assertIntEquals(0, main.smaliCmpGtDoubleSameConstant());
+    assertIntEquals(0, main.smaliCmpLtDoubleSameConstant());
+
+    assertIntEquals(1, main.smaliCmpGtFloatConstantWithNaN());
+    assertIntEquals(-1, main.smaliCmpLtFloatConstantWithNaN());
+    assertIntEquals(1, main.smaliCmpGtDoubleConstantWithNaN());
+    assertIntEquals(-1, main.smaliCmpLtDoubleConstantWithNaN());
+
     assertIntEquals(33, ReturnInt33());
     assertIntEquals(2147483647, ReturnIntMax());
     assertIntEquals(0, ReturnInt0());
@@ -1275,4 +1620,10 @@
     assertDoubleEquals(34, ReturnDouble34());
     assertDoubleEquals(99.25, ReturnDouble99P25());
   }
+
+  Main() throws ClassNotFoundException {
+    testCmp = Class.forName("TestCmp");
+  }
+
+  private Class<?> testCmp;
 }