Improved side-effects/can-throw information on intrinsics.

Rationale: improved side effect and exception analysis gives
           many more opportunities for GVN/LICM/BCE.

Change-Id: I8aa9b757d77c7bd9d58271204a657c2c525195b5
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index c3d2759..6e7ba40 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -616,6 +616,40 @@
     }
   }
 
+  static int[][] mA;
+
+  /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
+  /// CHECK-DAG: NullCheck
+  /// CHECK-DAG: ArrayLength
+  /// CHECK-DAG: BoundsCheck
+  /// CHECK-DAG: ArrayGet
+  /// CHECK-DAG: NullCheck
+  /// CHECK-DAG: ArrayLength
+  /// CHECK-DAG: BoundsCheck
+  /// CHECK-DAG: ArrayGet
+  /// CHECK-DAG: InvokeStaticOrDirect
+  /// CHECK-DAG: ArraySet
+
+  /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
+  /// CHECK-NOT: NullCheck
+  /// CHECK-NOT: ArrayLength
+  /// CHECK-NOT: BoundsCheck
+  /// CHECK-DAG: ArrayGet
+  /// CHECK-NOT: ArrayGet
+  /// CHECK-DAG: InvokeStaticOrDirect
+  /// CHECK-DAG: ArraySet
+  /// CHECK-DAG: Exit
+  /// CHECK-DAG: Deoptimize
+
+  static void dynamicBCEAndIntrinsic(int n) {
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < n; j++) {
+        // Since intrinsic call cannot modify fields or arrays,
+        // dynamic BCE and hoisting can be applied to the inner loop.
+        mA[i][j] = Math.abs(mA[i][j]);
+      }
+    }
+  }
 
   static int foo() {
     try {
@@ -1225,6 +1259,21 @@
       }
     }
 
+    mA = new int[4][4];
+    for (int i = 0; i < 4; i++) {
+      for (int j = 0; j < 4; j++) {
+        mA[i][j] = -1;
+      }
+    }
+    dynamicBCEAndIntrinsic(4);
+    for (int i = 0; i < 4; i++) {
+      for (int j = 0; j < 4; j++) {
+        if (mA[i][i] != 1) {
+          System.out.println("dynamic bce failed!");
+        }
+      }
+    }
+
     array = new int[7];
     pyramid1(array);
     if (!isPyramid(array)) {