8026844: Various Math functions needs intrinsification
authorrbackman
Fri, 18 Oct 2013 10:41:56 +0200
changeset 21105 47618ee96ed5
parent 21104 03d26ba7c343
child 21106 37ad7041ff83
8026844: Various Math functions needs intrinsification Reviewed-by: kvn, twisti
hotspot/src/cpu/sparc/vm/sparc.ad
hotspot/src/cpu/x86/vm/assembler_x86.cpp
hotspot/src/cpu/x86/vm/assembler_x86.hpp
hotspot/src/cpu/x86/vm/x86_32.ad
hotspot/src/cpu/x86/vm/x86_64.ad
hotspot/src/share/vm/adlc/archDesc.cpp
hotspot/src/share/vm/classfile/vmSymbols.hpp
hotspot/src/share/vm/opto/classes.hpp
hotspot/src/share/vm/opto/library_call.cpp
hotspot/src/share/vm/opto/matcher.hpp
hotspot/src/share/vm/opto/mathexactnode.cpp
hotspot/src/share/vm/opto/mathexactnode.hpp
hotspot/src/share/vm/opto/node.hpp
hotspot/src/share/vm/opto/type.cpp
hotspot/src/share/vm/opto/type.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
hotspot/test/compiler/intrinsics/mathexact/AddExactICondTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/CondTest.java
hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java
hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java
hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java
hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java
hotspot/test/compiler/intrinsics/mathexact/LoadTest.java
hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactICondTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java
hotspot/test/compiler/intrinsics/mathexact/Verify.java
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Oct 18 10:41:56 2013 +0200
@@ -2022,6 +2022,10 @@
   return G1_REGI_mask();
 }
 
+const RegMask Matcher::mathExactL_result_proj_mask() {
+  return G1_REGL_mask();
+}
+
 const RegMask Matcher::mathExactI_flags_proj_mask() {
   return INT_FLAGS_mask();
 }
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -1405,6 +1405,15 @@
   }
 }
 
+void Assembler::imull(Register dst, Address src) {
+  InstructionMark im(this);
+  prefix(src, dst);
+  emit_int8(0x0F);
+  emit_int8((unsigned char) 0xAF);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::incl(Address dst) {
   // Don't use it directly. Use MacroAssembler::increment() instead.
   InstructionMark im(this);
@@ -5024,6 +5033,14 @@
   }
 }
 
+void Assembler::imulq(Register dst, Address src) {
+  InstructionMark im(this);
+  prefixq(src, dst);
+  emit_int8(0x0F);
+  emit_int8((unsigned char) 0xAF);
+  emit_operand(dst, src);
+}
+
 void Assembler::incl(Register dst) {
   // Don't use it directly. Use MacroAssembler::incrementl() instead.
   // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -1162,9 +1162,13 @@
 
   void imull(Register dst, Register src);
   void imull(Register dst, Register src, int value);
+  void imull(Register dst, Address src);
 
   void imulq(Register dst, Register src);
   void imulq(Register dst, Register src, int value);
+#ifdef _LP64
+  void imulq(Register dst, Address src);
+#endif
 
 
   // jcc is the generic conditional branch generator to run-
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Fri Oct 18 10:41:56 2013 +0200
@@ -1538,6 +1538,11 @@
   return EAX_REG_mask();
 }
 
+const RegMask Matcher::mathExactL_result_proj_mask() {
+  ShouldNotReachHere();
+  return RegMask();
+}
+
 const RegMask Matcher::mathExactI_flags_proj_mask() {
   return INT_FLAGS_mask();
 }
@@ -7519,7 +7524,7 @@
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 
-instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
+instruct addExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
 %{
   match(AddExactI dst src);
   effect(DEF cr);
@@ -7531,7 +7536,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
+instruct addExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
 %{
   match(AddExactI dst src);
   effect(DEF cr);
@@ -7543,6 +7548,20 @@
   ins_pipe(ialu_reg_reg);
 %}
 
+instruct addExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
+%{
+  match(AddExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(125);
+  format %{ "ADD    $dst,$src\t# addExact int" %}
+  ins_encode %{
+    __ addl($dst$$Register, $src$$Address);
+  %}
+  ins_pipe( ialu_reg_mem );
+%}
+
+
 // Integer Addition Instructions
 instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (AddI dst src));
@@ -7851,6 +7870,44 @@
 %}
 
 //----------Subtraction Instructions-------------------------------------------
+
+instruct subExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
+%{
+  match(SubExactI dst src);
+  effect(DEF cr);
+
+  format %{ "SUB    $dst, $src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
+%{
+  match(SubExactI dst src);
+  effect(DEF cr);
+
+  format %{ "SUB    $dst, $src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$constant);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
+%{
+  match(SubExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(125);
+  format %{ "SUB    $dst,$src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$Address);
+  %}
+  ins_pipe( ialu_reg_mem );
+%}
+
 // Integer Subtraction Instructions
 instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (SubI dst src));
@@ -7919,6 +7976,16 @@
   ins_pipe( ialu_reg );
 %}
 
+instruct negExactI_eReg(eAXRegI dst, eFlagsReg cr) %{
+  match(NegExactI dst);
+  effect(DEF cr);
+
+  format %{ "NEG    $dst\t# negExact int"%}
+  ins_encode %{
+    __ negl($dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
 
 //----------Multiplication/Division Instructions-------------------------------
 // Integer Multiplication Instructions
@@ -8131,6 +8198,46 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct mulExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
+%{
+  match(MulExactI dst src);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "IMUL   $dst, $src\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+instruct mulExactI_eReg_imm(eAXRegI dst, rRegI src, immI imm, eFlagsReg cr)
+%{
+  match(MulExactI src imm);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "IMUL   $dst, $src, $imm\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Register, $imm$$constant);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+instruct mulExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
+%{
+  match(MulExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(350);
+  format %{ "IMUL   $dst, $src\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem_alu0);
+%}
+
+
 // Integer DIV with Register
 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
   match(Set rax (DivI rax div));
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Fri Oct 18 10:41:56 2013 +0200
@@ -1653,6 +1653,10 @@
   return INT_RAX_REG_mask();
 }
 
+const RegMask Matcher::mathExactL_result_proj_mask() {
+  return LONG_RAX_REG_mask();
+}
+
 const RegMask Matcher::mathExactI_flags_proj_mask() {
   return INT_FLAGS_mask();
 }
@@ -6962,6 +6966,58 @@
   ins_pipe(ialu_reg_reg);
 %}
 
+instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
+%{
+  match(AddExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(125); // XXX
+  format %{ "addl    $dst, $src\t# addExact int" %}
+  ins_encode %{
+    __ addl($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
+%{
+  match(AddExactL dst src);
+  effect(DEF cr);
+
+  format %{ "addq    $dst, $src\t# addExact long" %}
+  ins_encode %{
+    __ addq($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
+%{
+  match(AddExactL dst src);
+  effect(DEF cr);
+
+  format %{ "addq    $dst, $src\t# addExact long" %}
+  ins_encode %{
+    __ addq($dst$$Register, $src$$constant);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
+%{
+  match(AddExactL dst (LoadL src));
+  effect(DEF cr);
+
+  ins_cost(125); // XXX
+  format %{ "addq    $dst, $src\t# addExact long" %}
+  ins_encode %{
+    __ addq($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
 %{
   match(Set dst (AddI dst src));
@@ -7574,6 +7630,80 @@
   ins_pipe(ialu_mem_imm);
 %}
 
+instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
+%{
+  match(SubExactI dst src);
+  effect(DEF cr);
+
+  format %{ "subl    $dst, $src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
+%{
+  match(SubExactI dst src);
+  effect(DEF cr);
+
+  format %{ "subl    $dst, $src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$constant);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
+%{
+  match(SubExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(125);
+  format %{ "subl    $dst, $src\t# subExact int" %}
+  ins_encode %{
+    __ subl($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
+%{
+  match(SubExactL dst src);
+  effect(DEF cr);
+
+  format %{ "subq    $dst, $src\t# subExact long" %}
+  ins_encode %{
+    __ subq($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
+%{
+  match(SubExactL dst (LoadL src));
+  effect(DEF cr);
+
+  format %{ "subq    $dst, $src\t# subExact long" %}
+  ins_encode %{
+    __ subq($dst$$Register, $src$$constant);
+  %}
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
+%{
+  match(SubExactI dst src);
+  effect(DEF cr);
+
+  ins_cost(125);
+  format %{ "subq    $dst, $src\t# subExact long" %}
+  ins_encode %{
+    __ subq($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
 %{
   match(Set dst (SubL dst src));
@@ -7690,6 +7820,30 @@
   ins_pipe(ialu_reg);
 %}
 
+instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr)
+%{
+  match(NegExactI dst);
+  effect(KILL cr);
+
+  format %{ "negl    $dst\t# negExact int" %}
+  ins_encode %{
+    __ negl($dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr)
+%{
+  match(NegExactL dst);
+  effect(KILL cr);
+
+  format %{ "negq    $dst\t# negExact long" %}
+  ins_encode %{
+    __ negq($dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
 
 //----------Multiplication/Division Instructions-------------------------------
 // Integer Multiplication Instructions
@@ -7807,6 +7961,86 @@
   ins_pipe(ialu_reg_reg_alu0);
 %}
 
+
+instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
+%{
+  match(MulExactI dst src);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "imull   $dst, $src\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+
+instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr)
+%{
+  match(MulExactI src imm);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "imull   $dst, $src, $imm\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Register, $imm$$constant);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
+%{
+  match(MulExactI dst (LoadI src));
+  effect(DEF cr);
+
+  ins_cost(350);
+  format %{ "imull   $dst, $src\t# mulExact int" %}
+  ins_encode %{
+    __ imull($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem_alu0);
+%}
+
+instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
+%{
+  match(MulExactL dst src);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "imulq   $dst, $src\t# mulExact long" %}
+  ins_encode %{
+    __ imulq($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr)
+%{
+  match(MulExactL src imm);
+  effect(DEF cr);
+
+  ins_cost(300);
+  format %{ "imulq   $dst, $src, $imm\t# mulExact long" %}
+  ins_encode %{
+    __ imulq($dst$$Register, $src$$Register, $imm$$constant);
+  %}
+  ins_pipe(ialu_reg_reg_alu0);
+%}
+
+instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
+%{
+  match(MulExactL dst (LoadL src));
+  effect(DEF cr);
+
+  ins_cost(350);
+  format %{ "imulq   $dst, $src\t# mulExact long" %}
+  ins_encode %{
+    __ imulq($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem_alu0);
+%}
+
 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
                    rFlagsReg cr)
 %{
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -1193,6 +1193,13 @@
          || strcmp(idealName,"FastLock") == 0
          || strcmp(idealName,"FastUnlock") == 0
          || strcmp(idealName,"AddExactI") == 0
+         || strcmp(idealName,"AddExactL") == 0
+         || strcmp(idealName,"SubExactI") == 0
+         || strcmp(idealName,"SubExactL") == 0
+         || strcmp(idealName,"MulExactI") == 0
+         || strcmp(idealName,"MulExactL") == 0
+         || strcmp(idealName,"NegExactI") == 0
+         || strcmp(idealName,"NegExactL") == 0
          || strcmp(idealName,"FlagsProj") == 0
          || strcmp(idealName,"Bool") == 0
          || strcmp(idealName,"Binary") == 0 ) {
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -624,6 +624,7 @@
   do_class(java_lang_StrictMath,          "java/lang/StrictMath")                                                       \
   do_signature(double2_double_signature,  "(DD)D")                                                                      \
   do_signature(int2_int_signature,        "(II)I")                                                                      \
+  do_signature(long2_long_signature,      "(JJ)J")                                                                         \
                                                                                                                         \
   /* here are the math names, all together: */                                                                          \
   do_name(abs_name,"abs")       do_name(sin_name,"sin")         do_name(cos_name,"cos")                                 \
@@ -632,8 +633,11 @@
   do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
                                                                                                                         \
   do_name(addExact_name,"addExact")                                                                                     \
+  do_name(decrementExact_name,"decrementExact")                                                                         \
+  do_name(incrementExact_name,"incrementExact")                                                                         \
+  do_name(multiplyExact_name,"multiplyExact")                                                                           \
+  do_name(negateExact_name,"negateExact")                                                                               \
   do_name(subtractExact_name,"subtractExact")                                                                           \
-  do_name(multiplyExact_name,"multiplyExact")                                                                           \
                                                                                                                         \
   do_intrinsic(_dabs,                     java_lang_Math,         abs_name,   double_double_signature,           F_S)   \
   do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
@@ -647,7 +651,18 @@
   do_intrinsic(_dexp,                     java_lang_Math,         exp_name,   double_double_signature,           F_S)   \
   do_intrinsic(_min,                      java_lang_Math,         min_name,   int2_int_signature,                F_S)   \
   do_intrinsic(_max,                      java_lang_Math,         max_name,   int2_int_signature,                F_S)   \
-  do_intrinsic(_addExact,                 java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
+  do_intrinsic(_addExactI,                java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
+  do_intrinsic(_addExactL,                java_lang_Math,         addExact_name, long2_long_signature,           F_S)   \
+  do_intrinsic(_decrementExactI,          java_lang_Math,         decrementExact_name, int_int_signature,        F_S)   \
+  do_intrinsic(_decrementExactL,          java_lang_Math,         decrementExact_name, long2_long_signature,     F_S)   \
+  do_intrinsic(_incrementExactI,          java_lang_Math,         incrementExact_name, int_int_signature,        F_S)   \
+  do_intrinsic(_incrementExactL,          java_lang_Math,         incrementExact_name, long2_long_signature,     F_S)   \
+  do_intrinsic(_multiplyExactI,           java_lang_Math,         multiplyExact_name, int2_int_signature,        F_S)   \
+  do_intrinsic(_multiplyExactL,           java_lang_Math,         multiplyExact_name, long2_long_signature,      F_S)   \
+  do_intrinsic(_negateExactI,             java_lang_Math,         negateExact_name, int_int_signature,           F_S)   \
+  do_intrinsic(_negateExactL,             java_lang_Math,         negateExact_name, long_long_signature,         F_S)   \
+  do_intrinsic(_subtractExactI,           java_lang_Math,         subtractExact_name, int2_int_signature,        F_S)   \
+  do_intrinsic(_subtractExactL,           java_lang_Math,         subtractExact_name, long2_long_signature,      F_S)   \
                                                                                                                         \
   do_intrinsic(_floatToRawIntBits,        java_lang_Float,        floatToRawIntBits_name,   float_int_signature, F_S)   \
    do_name(     floatToRawIntBits_name,                          "floatToRawIntBits")                                   \
--- a/hotspot/src/share/vm/opto/classes.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/classes.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -30,6 +30,7 @@
 macro(AbsI)
 macro(AddD)
 macro(AddExactI)
+macro(AddExactL)
 macro(AddF)
 macro(AddI)
 macro(AddL)
@@ -170,6 +171,8 @@
 macro(Mach)
 macro(MachProj)
 macro(MathExact)
+macro(MathExactI)
+macro(MathExactL)
 macro(MaxI)
 macro(MemBarAcquire)
 macro(MemBarAcquireLock)
@@ -189,12 +192,16 @@
 macro(MoveL2D)
 macro(MoveD2L)
 macro(MulD)
+macro(MulExactI)
+macro(MulExactL)
 macro(MulF)
 macro(MulHiL)
 macro(MulI)
 macro(MulL)
 macro(Multi)
 macro(NegD)
+macro(NegExactI)
+macro(NegExactL)
 macro(NegF)
 macro(NeverBranch)
 macro(Opaque1)
@@ -244,6 +251,8 @@
 macro(StrEquals)
 macro(StrIndexOf)
 macro(SubD)
+macro(SubExactI)
+macro(SubExactL)
 macro(SubF)
 macro(SubI)
 macro(SubL)
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -203,8 +203,15 @@
   bool inline_math_native(vmIntrinsics::ID id);
   bool inline_trig(vmIntrinsics::ID id);
   bool inline_math(vmIntrinsics::ID id);
-  bool inline_math_mathExact(Node* math);
-  bool inline_math_addExact();
+  void inline_math_mathExact(Node* math);
+  bool inline_math_addExactI(bool is_increment);
+  bool inline_math_addExactL(bool is_increment);
+  bool inline_math_multiplyExactI();
+  bool inline_math_multiplyExactL();
+  bool inline_math_negateExactI();
+  bool inline_math_negateExactL();
+  bool inline_math_subtractExactI(bool is_decrement);
+  bool inline_math_subtractExactL(bool is_decrement);
   bool inline_exp();
   bool inline_pow();
   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
@@ -507,13 +514,33 @@
     if (!UseCRC32Intrinsics) return NULL;
     break;
 
-  case vmIntrinsics::_addExact:
-    if (!Matcher::match_rule_supported(Op_AddExactI)) {
-      return NULL;
-    }
-    if (!UseMathExactIntrinsics) {
-      return NULL;
-    }
+  case vmIntrinsics::_incrementExactI:
+  case vmIntrinsics::_addExactI:
+    if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_incrementExactL:
+  case vmIntrinsics::_addExactL:
+    if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_decrementExactI:
+  case vmIntrinsics::_subtractExactI:
+    if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_decrementExactL:
+  case vmIntrinsics::_subtractExactL:
+    if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_negateExactI:
+    if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_negateExactL:
+    if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_multiplyExactI:
+    if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
+    break;
+  case vmIntrinsics::_multiplyExactL:
+    if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
     break;
 
  default:
@@ -686,7 +713,18 @@
   case vmIntrinsics::_min:
   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 
-  case vmIntrinsics::_addExact:                 return inline_math_addExact();
+  case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
+  case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
+  case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
+  case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
+  case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
+  case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);
+  case vmIntrinsics::_multiplyExactI:           return inline_math_multiplyExactI();
+  case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
+  case vmIntrinsics::_negateExactI:             return inline_math_negateExactI();
+  case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
+  case vmIntrinsics::_subtractExactI:           return inline_math_subtractExactI(false /* subtract */);
+  case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL(false /* subtract */);
 
   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 
@@ -1931,7 +1969,14 @@
   return true;
 }
 
-bool LibraryCallKit::inline_math_mathExact(Node* math) {
+void LibraryCallKit::inline_math_mathExact(Node* math) {
+  // If we didn't get the expected opcode it means we have optimized
+  // the node to something else and don't need the exception edge.
+  if (!math->is_MathExact()) {
+    set_result(math);
+    return;
+  }
+
   Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
   Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
 
@@ -1954,19 +1999,106 @@
 
   set_control(fast_path);
   set_result(result);
+}
+
+bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
+  Node* arg1 = argument(0);
+  Node* arg2 = NULL;
+
+  if (is_increment) {
+      arg2 = intcon(1);
+  } else {
+      arg2 = argument(1);
+  }
+
+  Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
+  inline_math_mathExact(add);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
+  Node* arg1 = argument(0); // type long
+  // argument(1) == TOP
+  Node* arg2 = NULL;
+
+  if (is_increment) {
+    arg2 = longcon(1);
+  } else {
+    arg2 = argument(2); // type long
+    // argument(3) == TOP
+  }
+
+  Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
+  inline_math_mathExact(add);
   return true;
 }
 
-bool LibraryCallKit::inline_math_addExact() {
+bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
+  Node* arg1 = argument(0);
+  Node* arg2 = NULL;
+
+  if (is_decrement) {
+    arg2 = intcon(1);
+  } else {
+    arg2 = argument(1);
+  }
+
+  Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
+  inline_math_mathExact(sub);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
+  Node* arg1 = argument(0); // type long
+  // argument(1) == TOP
+  Node* arg2 = NULL;
+
+  if (is_decrement) {
+    arg2 = longcon(1);
+  } else {
+    Node* arg2 = argument(2); // type long
+    // argument(3) == TOP
+  }
+
+  Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
+  inline_math_mathExact(sub);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_negateExactI() {
+  Node* arg1 = argument(0);
+
+  Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
+  inline_math_mathExact(neg);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_negateExactL() {
+  Node* arg1 = argument(0);
+  // argument(1) == TOP
+
+  Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
+  inline_math_mathExact(neg);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_multiplyExactI() {
   Node* arg1 = argument(0);
   Node* arg2 = argument(1);
 
-  Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
-  if (add->Opcode() == Op_AddExactI) {
-    return inline_math_mathExact(add);
-  } else {
-    set_result(add);
-  }
+  Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
+  inline_math_mathExact(mul);
+  return true;
+}
+
+bool LibraryCallKit::inline_math_multiplyExactL() {
+  Node* arg1 = argument(0);
+  // argument(1) == TOP
+  Node* arg2 = argument(2);
+  // argument(3) == TOP
+
+  Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
+  inline_math_mathExact(mul);
   return true;
 }
 
--- a/hotspot/src/share/vm/opto/matcher.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -338,6 +338,7 @@
   static RegMask modL_proj_mask();
 
   static const RegMask mathExactI_result_proj_mask();
+  static const RegMask mathExactL_result_proj_mask();
   static const RegMask mathExactI_flags_proj_mask();
 
   // Use hardware DIV instruction when it is faster than
--- a/hotspot/src/share/vm/opto/mathexactnode.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/mathexactnode.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -31,10 +31,17 @@
 #include "opto/mathexactnode.hpp"
 #include "opto/subnode.hpp"
 
-MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) {
+MathExactNode::MathExactNode(Node* ctrl, Node* in1) : MultiNode(2) {
+  init_class_id(Class_MathExact);
   init_req(0, ctrl);
-  init_req(1, n1);
-  init_req(2, n2);
+  init_req(1, in1);
+}
+
+MathExactNode::MathExactNode(Node* ctrl, Node* in1, Node* in2) : MultiNode(3) {
+  init_class_id(Class_MathExact);
+  init_req(0, ctrl);
+  init_req(1, in1);
+  init_req(2, in2);
 }
 
 BoolNode* MathExactNode::bool_node() const {
@@ -64,23 +71,10 @@
   return ifnode->proj_out(1);
 }
 
-Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
-  uint ideal_reg = proj->ideal_reg();
-  RegMask rm;
-  if (proj->_con == result_proj_node) {
-    rm = m->mathExactI_result_proj_mask();
-  } else {
-    assert(proj->_con == flags_proj_node, "must be result or flags");
-    assert(ideal_reg == Op_RegFlags, "sanity");
-    rm = m->mathExactI_flags_proj_mask();
-  }
-  return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
-}
-
 // If the MathExactNode won't overflow we have to replace the
 // FlagsProjNode and ProjNode that is generated by the MathExactNode
-Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
-  PhaseIterGVN *igvn = phase->is_IterGVN();
+Node* MathExactNode::no_overflow(PhaseGVN* phase, Node* new_result) {
+  PhaseIterGVN* igvn = phase->is_IterGVN();
   if (igvn) {
     ProjNode* result = result_node();
     ProjNode* flags = flags_node();
@@ -110,9 +104,35 @@
   return new_result;
 }
 
-Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
-  Node *arg1 = in(1);
-  Node *arg2 = in(2);
+Node* MathExactINode::match(const ProjNode* proj, const Matcher* m) {
+  uint ideal_reg = proj->ideal_reg();
+  RegMask rm;
+  if (proj->_con == result_proj_node) {
+    rm = m->mathExactI_result_proj_mask();
+  } else {
+    assert(proj->_con == flags_proj_node, "must be result or flags");
+    assert(ideal_reg == Op_RegFlags, "sanity");
+    rm = m->mathExactI_flags_proj_mask();
+  }
+  return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
+}
+
+Node* MathExactLNode::match(const ProjNode* proj, const Matcher* m) {
+  uint ideal_reg = proj->ideal_reg();
+  RegMask rm;
+  if (proj->_con == result_proj_node) {
+    rm = m->mathExactL_result_proj_mask();
+  } else {
+    assert(proj->_con == flags_proj_node, "must be result or flags");
+    assert(ideal_reg == Op_RegFlags, "sanity");
+    rm = m->mathExactI_flags_proj_mask();
+  }
+  return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
+}
+
+Node* AddExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
 
   const Type* type1 = phase->type(arg1);
   const Type* type2 = phase->type(arg2);
@@ -130,12 +150,7 @@
     return NULL;
   }
 
-  if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
-    Node* add_result = new (phase->C) AddINode(arg1, arg2);
-    return no_overflow(phase, add_result);
-  }
-
-  if (type2 == TypeInt::ZERO) { // (Add x 0) == x
+  if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) { // (Add 0 x) == x
     Node* add_result = new (phase->C) AddINode(arg1, arg2);
     return no_overflow(phase, add_result);
   }
@@ -169,3 +184,247 @@
   return NULL;
 }
 
+Node* AddExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
+
+  const Type* type1 = phase->type(arg1);
+  const Type* type2 = phase->type(arg2);
+
+  if (type1 != Type::TOP && type1->singleton() &&
+      type2 != Type::TOP && type2->singleton()) {
+    jlong val1 = arg1->get_long();
+    jlong val2 = arg2->get_long();
+    jlong result = val1 + val2;
+    // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
+    if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
+      Node* con_result = ConLNode::make(phase->C, result);
+      return no_overflow(phase, con_result);
+    }
+    return NULL;
+  }
+
+  if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) { // (Add 0 x) == x
+    Node* add_result = new (phase->C) AddLNode(arg1, arg2);
+    return no_overflow(phase, add_result);
+  }
+
+  if (type2->singleton()) {
+    return NULL; // no change - keep constant on the right
+  }
+
+  if (type1->singleton()) {
+    // Make it x + Constant - move constant to the right
+    swap_edges(1, 2);
+    return this;
+  }
+
+  if (arg2->is_Load()) {
+    return NULL; // no change - keep load on the right
+  }
+
+  if (arg1->is_Load()) {
+    // Make it x + Load - move load to the right
+    swap_edges(1, 2);
+    return this;
+  }
+
+  if (arg1->_idx > arg2->_idx) {
+    // Sort the edges
+    swap_edges(1, 2);
+    return this;
+  }
+
+  return NULL;
+}
+
+Node* SubExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
+
+  const Type* type1 = phase->type(arg1);
+  const Type* type2 = phase->type(arg2);
+
+  if (type1 != Type::TOP && type1->singleton() &&
+      type2 != Type::TOP && type2->singleton()) {
+    jint val1 = arg1->get_int();
+    jint val2 = arg2->get_int();
+    jint result = val1 - val2;
+
+    // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
+    // the sign of the result is different than the sign of arg1
+    if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
+      Node* con_result = ConINode::make(phase->C, result);
+      return no_overflow(phase, con_result);
+    }
+    return NULL;
+  }
+
+  if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
+    // Sub with zero is the same as add with zero
+    Node* add_result = new (phase->C) AddINode(arg1, arg2);
+    return no_overflow(phase, add_result);
+  }
+
+  return NULL;
+}
+
+Node* SubExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
+
+  const Type* type1 = phase->type(arg1);
+  const Type* type2 = phase->type(arg2);
+
+  if (type1 != Type::TOP && type1->singleton() &&
+      type2 != Type::TOP && type2->singleton()) {
+    jlong val1 = arg1->get_long();
+    jlong val2 = arg2->get_long();
+    jlong result = val1 - val2;
+
+    // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
+    // the sign of the result is different than the sign of arg1
+    if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
+      Node* con_result = ConLNode::make(phase->C, result);
+      return no_overflow(phase, con_result);
+    }
+    return NULL;
+  }
+
+  if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
+    // Sub with zero is the same as add with zero
+    Node* add_result = new (phase->C) AddLNode(arg1, arg2);
+    return no_overflow(phase, add_result);
+  }
+
+  return NULL;
+}
+
+Node* NegExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node *arg = in(1);
+
+  const Type* type = phase->type(arg);
+  if (type != Type::TOP && type->singleton()) {
+    jint value = arg->get_int();
+    if (value != min_jint) {
+      Node* neg_result = ConINode::make(phase->C, -value);
+      return no_overflow(phase, neg_result);
+    }
+  }
+  return NULL;
+}
+
+Node* NegExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node *arg = in(1);
+
+  const Type* type = phase->type(arg);
+  if (type != Type::TOP && type->singleton()) {
+    jlong value = arg->get_long();
+    if (value != min_jlong) {
+      Node* neg_result = ConLNode::make(phase->C, -value);
+      return no_overflow(phase, neg_result);
+    }
+  }
+  return NULL;
+}
+
+Node* MulExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
+
+  const Type* type1 = phase->type(arg1);
+  const Type* type2 = phase->type(arg2);
+
+  if (type1 != Type::TOP && type1->singleton() &&
+      type2 != Type::TOP && type2->singleton()) {
+    jint val1 = arg1->get_int();
+    jint val2 = arg2->get_int();
+    jlong result = (jlong) val1 * (jlong) val2;
+    if ((jint) result == result) {
+      // no overflow
+      Node* mul_result = ConINode::make(phase->C, result);
+      return no_overflow(phase, mul_result);
+    }
+  }
+
+  if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
+    return no_overflow(phase, ConINode::make(phase->C, 0));
+  }
+
+  if (type1 == TypeInt::ONE) {
+    Node* mul_result = new (phase->C) AddINode(arg2, phase->intcon(0));
+    return no_overflow(phase, mul_result);
+  }
+  if (type2 == TypeInt::ONE) {
+    Node* mul_result = new (phase->C) AddINode(arg1, phase->intcon(0));
+    return no_overflow(phase, mul_result);
+  }
+
+  if (type1 == TypeInt::MINUS_1) {
+    return new (phase->C) NegExactINode(NULL, arg2);
+  }
+
+  if (type2 == TypeInt::MINUS_1) {
+    return new (phase->C) NegExactINode(NULL, arg1);
+  }
+
+  return NULL;
+}
+
+Node* MulExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+  Node* arg1 = in(1);
+  Node* arg2 = in(2);
+
+  const Type* type1 = phase->type(arg1);
+  const Type* type2 = phase->type(arg2);
+
+  if (type1 != Type::TOP && type1->singleton() &&
+      type2 != Type::TOP && type2->singleton()) {
+    jlong val1 = arg1->get_long();
+    jlong val2 = arg2->get_long();
+
+    jlong result = val1 * val2;
+    jlong ax = (val1 < 0 ? -val1 : val1);
+    jlong ay = (val2 < 0 ? -val2 : val2);
+
+    bool overflow = false;
+    if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
+      // potential overflow if any bit in upper 32 bits are set
+      if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
+        // -1 * Long.MIN_VALUE will overflow
+        overflow = true;
+      } else if (val2 != 0 && (result / val2 != val1)) {
+        overflow = true;
+      }
+    }
+
+    if (!overflow) {
+      Node* mul_result = ConLNode::make(phase->C, result);
+      return no_overflow(phase, mul_result);
+    }
+  }
+
+  if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
+    return no_overflow(phase, ConLNode::make(phase->C, 0));
+  }
+
+  if (type1 == TypeLong::ONE) {
+    Node* mul_result = new (phase->C) AddLNode(arg2, phase->longcon(0));
+    return no_overflow(phase, mul_result);
+  }
+  if (type2 == TypeLong::ONE) {
+    Node* mul_result = new (phase->C) AddLNode(arg1, phase->longcon(0));
+    return no_overflow(phase, mul_result);
+  }
+
+  if (type1 == TypeLong::MINUS_1) {
+    return new (phase->C) NegExactLNode(NULL, arg2);
+  }
+
+  if (type2 == TypeLong::MINUS_1) {
+    return new (phase->C) NegExactLNode(NULL, arg1);
+  }
+
+  return NULL;
+}
+
--- a/hotspot/src/share/vm/opto/mathexactnode.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/mathexactnode.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -39,6 +39,7 @@
 
 class MathExactNode : public MultiNode {
 public:
+  MathExactNode(Node* ctrl, Node* in1);
   MathExactNode(Node* ctrl, Node* in1, Node* in2);
   enum {
     result_proj_node = 0,
@@ -62,13 +63,78 @@
   Node* no_overflow(PhaseGVN *phase, Node* new_result);
 };
 
-class AddExactINode : public MathExactNode {
+class MathExactINode : public MathExactNode {
+ public:
+  MathExactINode(Node* ctrl, Node* in1) : MathExactNode(ctrl, in1) {}
+  MathExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* match(const ProjNode* proj, const Matcher* m);
+  virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
+};
+
+class MathExactLNode : public MathExactNode {
 public:
-  AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
+  MathExactLNode(Node* ctrl, Node* in1) : MathExactNode(ctrl, in1) {}
+  MathExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* match(const ProjNode* proj, const Matcher* m);
+  virtual const Type* bottom_type() const { return TypeTuple::LONG_CC_PAIR; }
+};
+
+class AddExactINode : public MathExactINode {
+public:
+  AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+};
+
+class AddExactLNode : public MathExactLNode {
+public:
+  AddExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class SubExactINode : public MathExactINode {
+public:
+  SubExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
   virtual int Opcode() const;
-  virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
-  virtual Node* match(const ProjNode* proj, const Matcher* m);
-  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class SubExactLNode : public MathExactLNode {
+public:
+  SubExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class NegExactINode : public MathExactINode {
+public:
+  NegExactINode(Node* ctrl, Node* in1) : MathExactINode(ctrl, in1) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class NegExactLNode : public MathExactLNode {
+public:
+  NegExactLNode(Node* ctrl, Node* in1) : MathExactLNode(ctrl, in1) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class MulExactINode : public MathExactINode {
+public:
+  MulExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+class MulExactLNode : public MathExactLNode {
+public:
+  MulExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
+  virtual int Opcode() const;
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
 };
 
 class FlagsProjNode : public ProjNode {
--- a/hotspot/src/share/vm/opto/node.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -100,6 +100,7 @@
 class MachSpillCopyNode;
 class MachTempNode;
 class Matcher;
+class MathExactNode;
 class MemBarNode;
 class MemBarStoreStoreNode;
 class MemNode;
@@ -568,6 +569,7 @@
       DEFINE_CLASS_ID(MemBar,      Multi, 3)
         DEFINE_CLASS_ID(Initialize,       MemBar, 0)
         DEFINE_CLASS_ID(MemBarStoreStore, MemBar, 1)
+      DEFINE_CLASS_ID(MathExact,   Multi, 4)
 
     DEFINE_CLASS_ID(Mach,  Node, 1)
       DEFINE_CLASS_ID(MachReturn, Mach, 0)
@@ -757,6 +759,7 @@
   DEFINE_CLASS_QUERY(MachSafePoint)
   DEFINE_CLASS_QUERY(MachSpillCopy)
   DEFINE_CLASS_QUERY(MachTemp)
+  DEFINE_CLASS_QUERY(MathExact)
   DEFINE_CLASS_QUERY(Mem)
   DEFINE_CLASS_QUERY(MemBar)
   DEFINE_CLASS_QUERY(MemBarStoreStore)
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -435,6 +435,11 @@
   intccpair[1] = TypeInt::CC;
   TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair);
 
+  const Type **longccpair = TypeTuple::fields(2);
+  longccpair[0] = TypeLong::LONG;
+  longccpair[1] = TypeInt::CC;
+  TypeTuple::LONG_CC_PAIR = TypeTuple::make(2, longccpair);
+
   _const_basic_type[T_NARROWOOP]   = TypeNarrowOop::BOTTOM;
   _const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
   _const_basic_type[T_BOOLEAN]     = TypeInt::BOOL;
@@ -1675,6 +1680,7 @@
 const TypeTuple *TypeTuple::INT_PAIR;
 const TypeTuple *TypeTuple::LONG_PAIR;
 const TypeTuple *TypeTuple::INT_CC_PAIR;
+const TypeTuple *TypeTuple::LONG_CC_PAIR;
 
 
 //------------------------------make-------------------------------------------
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp	Fri Oct 18 10:41:56 2013 +0200
@@ -593,6 +593,7 @@
   static const TypeTuple *INT_PAIR;
   static const TypeTuple *LONG_PAIR;
   static const TypeTuple *INT_CC_PAIR;
+  static const TypeTuple *LONG_CC_PAIR;
 #ifndef PRODUCT
   virtual void dump2( Dict &d, uint, outputStream *st  ) const; // Specialized per-Type dumping
 #endif
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri Oct 18 10:41:56 2013 +0200
@@ -1938,7 +1938,13 @@
   declare_c2_type(CmpDNode, CmpNode)                                      \
   declare_c2_type(CmpD3Node, CmpDNode)                                    \
   declare_c2_type(MathExactNode, MultiNode)                               \
-  declare_c2_type(AddExactINode, MathExactNode)                           \
+  declare_c2_type(MathExactINode, MathExactNode)                          \
+  declare_c2_type(AddExactINode, MathExactINode)                          \
+  declare_c2_type(AddExactLNode, MathExactLNode)                          \
+  declare_c2_type(SubExactINode, MathExactINode)                          \
+  declare_c2_type(SubExactLNode, MathExactLNode)                          \
+  declare_c2_type(NegExactINode, MathExactINode)                          \
+  declare_c2_type(MulExactINode, MathExactINode)                          \
   declare_c2_type(FlagsProjNode, ProjNode)                                \
   declare_c2_type(BoolNode, Node)                                         \
   declare_c2_type(AbsNode, Node)                                          \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactICondTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024924
+ * @summary Test non constant addExact
+ * @compile AddExactICondTest.java
+ * @run main AddExactICondTest
+ *
+ */
+
+public class AddExactICondTest {
+  public static int result = 0;
+
+  public static void main(String[] args) {
+    for (int i = 0; i < 50000; ++i) {
+      runTest();
+    }
+  }
+
+  public static void runTest() {
+    int i = 7;
+    while (java.lang.Math.addExact(i, result) < 89361) {
+        if ((java.lang.Math.addExact(i, i) & 1) == 1) {
+            i += 3;
+        } else if ((i & 5) == 4) {
+            i += 7;
+        } else if ((i & 0xf) == 6) {
+            i += 2;
+        } else {
+            i += 1;
+        }
+        result += 2;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024924
+ * @summary Test constant addExact
+ * @compile AddExactIConstantTest.java Verify.java
+ * @run main AddExactIConstantTest
+ *
+ */
+
+public class AddExactIConstantTest {
+  public static void main(String[] args) {
+      Verify.ConstantTest.verify(new Verify.AddExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024924
+ * @summary Test non constant addExact
+ * @compile AddExactILoadTest.java Verify.java
+ * @run main AddExactILoadTest
+ *
+ */
+
+public class AddExactILoadTest {
+  public static void main(String[] args) {
+      Verify.LoadTest.init();
+      Verify.LoadTest.verify(new Verify.AddExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024924
+ * @summary Test non constant addExact
+ * @compile AddExactILoopDependentTest.java Verify.java
+ * @run main AddExactILoopDependentTest
+ *
+ */
+
+public class AddExactILoopDependentTest {
+  public static void main(String[] args) {
+    Verify.LoopDependentTest.verify(new Verify.AddExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024924
+ * @summary Test non constant addExact
+ * @compile AddExactINonConstantTest.java Verify.java
+ * @run main AddExactINonConstantTest
+ *
+ */
+
+public class AddExactINonConstantTest {
+  public static void main(String[] args) {
+      Verify.NonConstantTest.verify(new Verify.AddExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8025657
+ * @summary Test repeating addExact
+ * @compile AddExactIRepeatTest.java Verify.java
+ * @run main AddExactIRepeatTest
+ *
+ */
+
+public class AddExactIRepeatTest {
+    public static void main(String[] args) {
+        runTest(new Verify.AddExactI());
+    }
+
+    public static int nonExact(int x, int y, Verify.BinaryMethod method) {
+        int result = method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        return result;
+    }
+
+    public static void runTest(Verify.BinaryMethod method) {
+        java.util.Random rnd = new java.util.Random();
+        for (int i = 0; i < 50000; ++i) {
+            int x = Integer.MAX_VALUE - 10;
+            int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
+
+            int c = rnd.nextInt() / 2;
+            int d = rnd.nextInt() / 2;
+
+            int a = catchingExact(x, y, method);
+
+            if (a != 36) {
+                throw new RuntimeException("a != 36 : " + a);
+            }
+
+            int b = nonExact(c, d, method);
+            int n = exact(c, d, method);
+
+
+            if (n != b) {
+                throw new RuntimeException("n != b : " + n + " != " + b);
+            }
+        }
+    }
+
+    public static int exact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        return result;
+    }
+
+    public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        try {
+            result += 5;
+            result = method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 1;
+        }
+        try {
+            result += 6;
+
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 2;
+        }
+        try {
+            result += 7;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 3;
+        }
+        try {
+            result += 8;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 4;
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant addExact
+ * @compile AddExactLConstantTest.java Verify.java
+ * @run main AddExactLConstantTest
+ *
+ */
+
+public class AddExactLConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantLongTest.verify(new Verify.AddExactL());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant addExact
+ * @compile AddExactLNonConstantTest.java Verify.java
+ * @run main AddExactLNonConstantTest
+ *
+ */
+
+public class AddExactLNonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantLongTest.verify(new Verify.AddExactL());
+    }
+}
--- a/hotspot/test/compiler/intrinsics/mathexact/CondTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8024924
- * @summary Test non constant addExact
- * @compile CondTest.java Verify.java
- * @run main CondTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class CondTest {
-  public static int result = 0;
-
-  public static void main(String[] args) {
-    for (int i = 0; i < 50000; ++i) {
-      runTest();
-    }
-  }
-
-  public static void runTest() {
-    int i = 7;
-    while (java.lang.Math.addExact(i, result) < 89361) {
-        if ((java.lang.Math.addExact(i, i) & 1) == 1) {
-            i += 3;
-        } else if ((i & 5) == 4) {
-            i += 7;
-        } else if ((i & 0xf) == 6) {
-            i += 2;
-        } else {
-            i += 1;
-        }
-        result += 2;
-    }
-  }
-}
--- a/hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8024924
- * @summary Test constant addExact
- * @compile ConstantTest.java Verify.java
- * @run main ConstantTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class ConstantTest {
-  public static void main(String[] args) {
-    for (int i = 0; i < 50000; ++i) {
-      Verify.verify(5, 7);
-      Verify.verify(Integer.MAX_VALUE, 1);
-      Verify.verify(Integer.MIN_VALUE, -1);
-      Verify.verify(Integer.MAX_VALUE, -1);
-      Verify.verify(Integer.MIN_VALUE, 1);
-      Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2);
-      Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3);
-    }
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test decrementExact
+ * @compile DecExactITest.java Verify.java
+ * @run main DecExactITest
+ *
+ */
+
+public class DecExactITest {
+    public static int[] values = {1, 1, 1, 1};
+    public static int[] minvalues = {Integer.MIN_VALUE, Integer.MIN_VALUE};
+
+    public static void main(String[] args) {
+        runTest(new Verify.DecExactI());
+    }
+
+    public static void runTest(Verify.UnaryMethod method) {
+        for (int i = 0; i < 20000; ++i) {
+            Verify.verifyUnary(Integer.MIN_VALUE, method);
+            Verify.verifyUnary(minvalues[0], method);
+            Verify.verifyUnary(Integer.MIN_VALUE - values[2], method);
+            Verify.verifyUnary(0, method);
+            Verify.verifyUnary(values[2], method);
+            Verify.verifyUnary(Integer.MAX_VALUE, method);
+            Verify.verifyUnary(Integer.MIN_VALUE - values[0] + values[3], method);
+            Verify.verifyUnary(Integer.MIN_VALUE + 1 - values[0], method);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test decrementExact
+ * @compile DecExactITest.java Verify.java
+ * @run main DecExactITest
+ *
+ */
+
+public class DecExactLTest {
+    public static long[] values = {1, 1, 1, 1};
+    public static long[] minvalues = {Long.MIN_VALUE, Long.MIN_VALUE};
+
+    public static void main(String[] args) {
+        runTest(new Verify.DecExactL());
+    }
+
+    public static void runTest(Verify.UnaryLongMethod method) {
+        for (int i = 0; i < 20000; ++i) {
+            Verify.verifyUnary(Long.MIN_VALUE, method);
+            Verify.verifyUnary(minvalues[0], method);
+            Verify.verifyUnary(Long.MIN_VALUE - values[2], method);
+            Verify.verifyUnary(0, method);
+            Verify.verifyUnary(values[2], method);
+            Verify.verifyUnary(Long.MAX_VALUE, method);
+            Verify.verifyUnary(Long.MIN_VALUE - values[0] + values[3], method);
+            Verify.verifyUnary(Long.MIN_VALUE + 1 - values[0], method);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test incrementExact
+ * @compile IncExactITest.java Verify.java
+ * @run main IncExactITest
+ *
+ */
+
+
+public class IncExactITest {
+    public static int[] values = {1, 1, 1, 1};
+    public static void main(String[] args) {
+        runTest(new Verify.IncExactI());
+    }
+
+    public static void runTest(Verify.UnaryMethod method) {
+        for (int i = 0; i < 20000; ++i) {
+            Verify.verifyUnary(Integer.MIN_VALUE, method);
+            Verify.verifyUnary(Integer.MAX_VALUE - 1, method);
+            Verify.verifyUnary(0, method);
+            Verify.verifyUnary(values[1], method);
+            Verify.verifyUnary(Integer.MAX_VALUE, method);
+            Verify.verifyUnary(Integer.MAX_VALUE - values[0] + values[3], method);
+            Verify.verifyUnary(Integer.MAX_VALUE - 1 + values[0], method);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test incrementExact
+ * @compile IncExactLTest.java Verify.java
+ * @run main IncExactLTest
+ *
+ */
+
+public class IncExactLTest {
+    public static long[] values = {1, 1, 1, 1};
+    public static void main(String[] args) {
+        runTest(new Verify.IncExactL());
+    }
+
+    public static void runTest(Verify.UnaryLongMethod method) {
+        for (int i = 0; i < 20000; ++i) {
+            Verify.verifyUnary(Long.MIN_VALUE, method);
+            Verify.verifyUnary(Long.MAX_VALUE - 1, method);
+            Verify.verifyUnary(0, method);
+            Verify.verifyUnary(values[1], method);
+            Verify.verifyUnary(Long.MAX_VALUE, method);
+            Verify.verifyUnary(Long.MAX_VALUE - values[0] + values[3], method);
+            Verify.verifyUnary(Long.MAX_VALUE - 1 + values[0], method);
+        }
+    }
+}
--- a/hotspot/test/compiler/intrinsics/mathexact/LoadTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8024924
- * @summary Test non constant addExact
- * @compile LoadTest.java Verify.java
- * @run main LoadTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class LoadTest {
-  public static java.util.Random rnd = new java.util.Random();
-  public static int[] values = new int[256];
-
-  public static void main(String[] args) {
-    for (int i = 0; i < values.length; ++i) {
-        values[i] = rnd.nextInt();
-    }
-
-    for (int i = 0; i < 50000; ++i) {
-      Verify.verify(values[i & 255], values[i & 255] - i);
-      Verify.verify(values[i & 255] + i, values[i & 255] - i);
-      Verify.verify(values[i & 255], values[i & 255]);
-      if ((i & 1) == 1 && i > 5) {
-          Verify.verify(values[i & 255] + i, values[i & 255] - i);
-      } else {
-          Verify.verify(values[i & 255] - i, values[i & 255] + i);
-      }
-    }
-  }
-}
--- a/hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8024924
- * @summary Test non constant addExact
- * @compile LoopDependentTest.java Verify.java
- * @run main LoopDependentTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class LoopDependentTest {
-  public static java.util.Random rnd = new java.util.Random();
-
-  public static void main(String[] args) {
-    int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
-    for (int i = 0; i < 50000; ++i) {
-      Verify.verify(rnd1 + i, rnd2 + i);
-      Verify.verify(rnd1 + i, rnd2 + (i & 0xff));
-      Verify.verify(rnd1 - i, rnd2 - (i & 0xff));
-      Verify.verify(rnd1 + i + 1, rnd2 + i + 2);
-      Verify.verify(rnd1 + i * 2, rnd2 + i);
-    }
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactICondTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test multiplyExact as condition
+ * @compile MulExactICondTest.java
+ * @run main MulExactICondTest
+ *
+ */
+
+public class MulExactICondTest {
+    public static int result = 0;
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 50000; ++i) {
+            runTest();
+        }
+    }
+
+    public static void runTest() {
+        int i = 7;
+        while (java.lang.Math.multiplyExact(i, result) < 89361) {
+            if ((java.lang.Math.multiplyExact(i, i) & 1) == 1) {
+                i += 3;
+            } else if ((i & 5) == 4) {
+                i += 7;
+            } else if ((i & 0xf) == 6) {
+                i += 2;
+            } else {
+                i += 1;
+            }
+            result += 2;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant multiplyExact
+ * @compile MulExactIConstantTest.java Verify.java
+ * @run main MulExactIConstantTest
+ *
+ */
+
+public class MulExactIConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantTest.verify(new Verify.MulExactI());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test multiplyExact
+ * @compile MulExactILoadTest.java Verify.java
+ * @run main MulExactILoadTest
+ *
+ */
+
+public class MulExactILoadTest {
+    public static void main(String[] args) {
+        Verify.LoadTest.init();
+        Verify.LoadTest.verify(new Verify.MulExactI());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test loop dependent multiplyExact
+ * @compile MulExactILoopDependentTest.java Verify.java
+ * @run main MulExactILoopDependentTest
+ *
+ */
+public class MulExactILoopDependentTest {
+    public static void main(String[] args) {
+        Verify.LoopDependentTest.verify(new Verify.MulExactI());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant multiplyExact
+ * @compile MulExactINonConstantTest.java Verify.java
+ * @run main MulExactINonConstantTest
+ *
+ */
+
+public class MulExactINonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantTest.verify(new Verify.MulExactI());
+        Verify.LoadTest.verify(new Verify.MulExactI());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test repeating multiplyExact
+ * @compile MulExactIRepeatTest.java Verify.java
+ * @run main MulExactIRepeatTest
+ *
+ */
+
+public class MulExactIRepeatTest {
+    public static void main(String[] args) {
+        runTest(new Verify.MulExactI());
+    }
+
+    public static int nonExact(int x, int y, Verify.BinaryMethod method) {
+        int result = method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        return result;
+    }
+
+    public static void runTest(Verify.BinaryMethod method) {
+        java.util.Random rnd = new java.util.Random();
+        for (int i = 0; i < 50000; ++i) {
+            int x = Integer.MAX_VALUE - 10;
+            int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
+
+            int c = rnd.nextInt() / 10;
+            int d = rnd.nextInt(9);
+
+            int a = catchingExact(x, y, method);
+
+            if (a != 36) {
+                throw new RuntimeException("a != 36 : " + a);
+            }
+
+            int b = nonExact(c, d, method);
+            int n = exact(c, d, method);
+
+
+            if (n != b) {
+                throw new RuntimeException("n != b : " + n + " != " + b);
+            }
+        }
+    }
+
+    public static int exact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        return result;
+    }
+
+    public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        try {
+            result += 5;
+            result = method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 1;
+        }
+        try {
+            result += 6;
+
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 2;
+        }
+        try {
+            result += 7;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 3;
+        }
+        try {
+            result += 8;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 4;
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant mulExact
+ * @compile MulExactLConstantTest.java Verify.java
+ * @run main MulExactLConstantTest
+ *
+ */
+
+public class MulExactLConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantLongTest.verify(new Verify.MulExactL());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant mulExact
+ * @compile MulExactLNonConstantTest.java Verify.java
+ * @run main MulExactLNonConstantTest
+ *
+ */
+
+public class MulExactLNonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantLongTest.verify(new Verify.MulExactL());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant negExact
+ * @compile NegExactIConstantTest.java Verify.java
+ * @run main NegExactIConstantTest
+ *
+ */
+
+public class NegExactIConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test negExact
+ * @compile NegExactILoadTest.java Verify.java
+ * @run main NegExactILoadTest
+ *
+ */
+
+public class NegExactILoadTest {
+    public static void main(String[] args) {
+        Verify.LoadTest.init();
+        Verify.LoadTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test negExact loop dependent
+ * @compile NegExactILoopDependentTest.java Verify.java
+ * @run main NegExactILoopDependentTest
+ *
+ */
+public class NegExactILoopDependentTest {
+    public static void main(String[] args) {
+        Verify.LoopDependentTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant negExact
+ * @compile NegExactINonConstantTest.java Verify.java
+ * @run main NegExactINonConstantTest
+ *
+ */
+
+public class NegExactINonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant negExact
+ * @compile NegExactLConstantTest.java Verify.java
+ * @run main NegExactLConstantTest
+ *
+ */
+
+public class NegExactLConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantLongTest.verify(new Verify.UnaryToBinaryLong(new Verify.NegExactL()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant negExact
+ * @compile NegExactLNonConstantTest.java Verify.java
+ * @run main NegExactLNonConstantTest
+ *
+ */
+
+public class NegExactLNonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantLongTest.verify(new Verify.UnaryToBinaryLong(new Verify.NegExactL()));
+    }
+}
--- a/hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8024924
- * @summary Test non constant addExact
- * @compile NonConstantTest.java Verify.java
- * @run main NonConstantTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class NonConstantTest {
-  public static java.util.Random rnd = new java.util.Random();
-
-  public static void main(String[] args) {
-    for (int i = 0; i < 50000; ++i) {
-      int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
-      Verify.verify(rnd1, rnd2);
-      Verify.verify(rnd1, rnd2 + 1);
-      Verify.verify(rnd1 + 1, rnd2);
-      Verify.verify(rnd1 - 1, rnd2);
-      Verify.verify(rnd1, rnd2 - 1);
-    }
-  }
-}
--- a/hotspot/test/compiler/intrinsics/mathexact/RepeatTest.java	Wed Oct 23 16:25:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8025657
- * @summary Test repeating addExact
- * @compile RepeatTest.java
- * @run main RepeatTest
- *
- */
-
-import java.lang.ArithmeticException;
-
-public class RepeatTest {
-  public static void main(String[] args) {
-    java.util.Random rnd = new java.util.Random();
-    for (int i = 0; i < 50000; ++i) {
-      int x = Integer.MAX_VALUE - 10;
-      int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5); //rnd.nextInt() / 2;
-
-      int c = rnd.nextInt() / 2;
-      int d = rnd.nextInt() / 2;
-
-      int a = addExact(x, y);
-
-      if (a != 36) {
-          throw new RuntimeException("a != 0 : " + a);
-      }
-
-      int b = nonExact(c, d);
-      int n = addExact2(c, d);
-
-
-      if (n != b) {
-        throw new RuntimeException("n != b : " + n + " != " + b);
-      }
-    }
-  }
-
-  public static int addExact2(int x, int y) {
-      int result = 0;
-      result += java.lang.Math.addExact(x, y);
-      result += java.lang.Math.addExact(x, y);
-      result += java.lang.Math.addExact(x, y);
-      result += java.lang.Math.addExact(x, y);
-      return result;
-  }
-
-  public static int addExact(int x, int y) {
-    int result = 0;
-    try {
-        result += 5;
-        result = java.lang.Math.addExact(x, y);
-    } catch (ArithmeticException e) {
-        result += 1;
-    }
-    try {
-        result += 6;
-
-        result += java.lang.Math.addExact(x, y);
-    } catch (ArithmeticException e) {
-        result += 2;
-    }
-    try {
-        result += 7;
-        result += java.lang.Math.addExact(x, y);
-    } catch (ArithmeticException e) {
-        result += 3;
-    }
-    try {
-        result += 8;
-        result += java.lang.Math.addExact(x, y);
-    } catch (ArithmeticException e) {
-        result += 4;
-    }
-    return result;
-  }
-
-  public static int nonExact(int x, int y) {
-    int result = x + y;
-    result += x + y;
-    result += x + y;
-    result += x + y;
-    return result;
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test subtractExact as condition
+ * @compile SubExactICondTest.java Verify.java
+ * @run main SubExactICondTest
+ *
+ */
+
+public class SubExactICondTest {
+  public static int result = 0;
+
+  public static void main(String[] args) {
+    for (int i = 0; i < 50000; ++i) {
+      runTest();
+    }
+  }
+
+  public static void runTest() {
+    int i = 7;
+    while (java.lang.Math.subtractExact(i, result) > -31361) {
+        if ((java.lang.Math.subtractExact(i, i) & 1) == 1) {
+            i -= 3;
+        } else if ((i & 5) == 4) {
+            i -= 7;
+        } else if ((i & 0xf) == 6) {
+            i -= 2;
+        } else {
+            i -= 1;
+        }
+        result += 2;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant subtractExact
+ * @compile SubExactIConstantTest.java Verify.java
+ * @run main SubExactIConstantTest
+ *
+ */
+
+public class SubExactIConstantTest {
+  public static void main(String[] args) {
+      Verify.ConstantTest.verify(new Verify.SubExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant subtractExact
+ * @compile SubExactILoadTest.java Verify.java
+ * @run main SubExactILoadTest
+ *
+ */
+
+public class SubExactILoadTest {
+  public static void main(String[] args) {
+      Verify.LoadTest.init();
+      Verify.LoadTest.verify(new Verify.SubExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant subtractExact
+ * @compile SubExactILoopDependentTest.java Verify.java
+ * @run main SubExactILoopDependentTest
+ *
+ */
+
+public class SubExactILoopDependentTest {
+  public static void main(String[] args) {
+      Verify.LoopDependentTest.verify(new Verify.SubExactI());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant subtractExact
+ * @compile SubExactINonConstantTest.java Verify.java
+ * @run main SubExactINonConstantTest
+ *
+ */
+
+public class SubExactINonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantTest.verify(new Verify.SubExactI());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test repeating subtractExact
+ * @compile SubExactIRepeatTest.java Verify.java
+ * @run main SubExactIRepeatTest
+ *
+ */
+
+import java.lang.ArithmeticException;
+
+public class SubExactIRepeatTest {
+    public static void main(String[] args) {
+        runTest(new Verify.SubExactI());
+    }
+
+    public static int nonExact(int x, int y, Verify.BinaryMethod method) {
+        int result = method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        result += method.unchecked(x, y);
+        return result;
+    }
+
+    public static void runTest(Verify.BinaryMethod method) {
+        java.util.Random rnd = new java.util.Random();
+        for (int i = 0; i < 50000; ++i) {
+            int x = Integer.MIN_VALUE + 10;
+            int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
+
+            int c = rnd.nextInt() / 2;
+            int d = rnd.nextInt() / 2;
+
+            int a = catchingExact(x, y, method);
+
+            if (a != 36) {
+                throw new RuntimeException("a != 36 : " + a);
+            }
+
+            int b = nonExact(c, d, method);
+            int n = exact(c, d, method);
+
+
+            if (n != b) {
+                throw new RuntimeException("n != b : " + n + " != " + b);
+            }
+        }
+    }
+
+    public static int exact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        result += method.checkMethod(x, y);
+        return result;
+    }
+
+    public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
+        int result = 0;
+        try {
+            result += 5;
+            result = method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 1;
+        }
+        try {
+            result += 6;
+
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 2;
+        }
+        try {
+            result += 7;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 3;
+        }
+        try {
+            result += 8;
+            result += method.checkMethod(x, y);
+        } catch (ArithmeticException e) {
+            result += 4;
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test constant subtractExact
+ * @compile SubExactLConstantTest.java Verify.java
+ * @run main SubExactLConstantTest
+ *
+ */
+
+public class SubExactLConstantTest {
+    public static void main(String[] args) {
+        Verify.ConstantLongTest.verify(new Verify.SubExactL());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java	Fri Oct 18 10:41:56 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8026844
+ * @summary Test non constant subtractExact
+ * @compile SubExactLNonConstantTest.java Verify.java
+ * @run main SubExactLNonConstantTest
+ *
+ */
+
+public class SubExactLNonConstantTest {
+    public static void main(String[] args) {
+        Verify.NonConstantLongTest.verify(new Verify.SubExactL());
+    }
+}
--- a/hotspot/test/compiler/intrinsics/mathexact/Verify.java	Wed Oct 23 16:25:48 2013 -0700
+++ b/hotspot/test/compiler/intrinsics/mathexact/Verify.java	Fri Oct 18 10:41:56 2013 +0200
@@ -22,47 +22,641 @@
  */
 
 public class Verify {
-  public static String throwWord(boolean threw) {
-    return (threw ? "threw" : "didn't throw");
-  }
+    public static String throwWord(boolean threw) {
+        return (threw ? "threw" : "didn't throw");
+    }
+
+    public static void verifyResult(UnaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int value) {
+        if (exception1 != exception2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
+        }
+        if (result1 != result2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
+        }
+    }
+
+    public static void verifyResult(UnaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long value) {
+        if (exception1 != exception2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
+        }
+        if (result1 != result2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
+        }
+    }
+
+    private static void verifyResult(BinaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int a, int b) {
+        if (exception1 != exception2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
+        }
+        if (result1 != result2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
+        }
+    }
+
+    private static void verifyResult(BinaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long a, long b) {
+        if (exception1 != exception2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
+        }
+        if (result1 != result2) {
+            throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
+        }
+    }
+
+
+    public static void verifyUnary(int a, UnaryMethod method) {
+        boolean exception1 = false, exception2 = false;
+        int result1 = 0, result2 = 0;
+        try {
+            result1 = method.checkMethod(a);
+        } catch (ArithmeticException e) {
+            exception1 = true;
+        }
+        try {
+            result2 = method.safeMethod(a);
+        } catch (ArithmeticException e) {
+            exception2 = true;
+        }
+
+        verifyResult(method, result1, result2, exception1, exception2, a);
+    }
+
+    public static void verifyUnary(long a, UnaryLongMethod method) {
+        boolean exception1 = false, exception2 = false;
+        long result1 = 0, result2 = 0;
+        try {
+            result1 = method.checkMethod(a);
+        } catch (ArithmeticException e) {
+            exception1 = true;
+        }
+        try {
+            result2 = method.safeMethod(a);
+        } catch (ArithmeticException e) {
+            exception2 = true;
+        }
+
+        verifyResult(method, result1, result2, exception1, exception2, a);
+    }
+
+
+    public static void verifyBinary(int a, int b, BinaryMethod method) {
+        boolean exception1 = false, exception2 = false;
+        int result1 = 0, result2 = 0;
+        try {
+            result1 = method.checkMethod(a, b);
+        } catch (ArithmeticException e) {
+            exception1 = true;
+        }
+        try {
+            result2 = method.safeMethod(a, b);
+        } catch (ArithmeticException e) {
+            exception2 = true;
+        }
+
+        verifyResult(method, result1, result2, exception1, exception2, a, b);
+    }
+
+    public static void verifyBinary(long a, long b, BinaryLongMethod method) {
+        boolean exception1 = false, exception2 = false;
+        long result1 = 0, result2 = 0;
+        try {
+            result1 = method.checkMethod(a, b);
+        } catch (ArithmeticException e) {
+            exception1 = true;
+        }
+        try {
+            result2 = method.safeMethod(a, b);
+        } catch (ArithmeticException e) {
+            exception2 = true;
+        }
+
+        verifyResult(method, result1, result2, exception1, exception2, a, b);
+    }
+
+
+    public static class LoadTest {
+        public static java.util.Random rnd = new java.util.Random();
+        public static int[] values = new int[256];
+
+        public static void init() {
+            for (int i = 0; i < values.length; ++i) {
+                values[i] = rnd.nextInt();
+            }
+        }
+
+        public static void verify(BinaryMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                Verify.verifyBinary(values[i & 255], values[i & 255] - i, method);
+                Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
+                Verify.verifyBinary(values[i & 255], values[i & 255], method);
+                if ((i & 1) == 1 && i > 5) {
+                    Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
+                } else {
+                    Verify.verifyBinary(values[i & 255] - i, values[i & 255] + i, method);
+                }
+                Verify.verifyBinary(values[i & 255], values[(i + 1) & 255], method);
+            }
+        }
+    }
+
+    public static class NonConstantTest {
+        public static java.util.Random rnd = new java.util.Random();
+
+        public static void verify(BinaryMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
+                Verify.verifyBinary(rnd1, rnd2, method);
+                Verify.verifyBinary(rnd1, rnd2 + 1, method);
+                Verify.verifyBinary(rnd1 + 1, rnd2, method);
+                Verify.verifyBinary(rnd1 - 1, rnd2, method);
+                Verify.verifyBinary(rnd1, rnd2 - 1, method);
+            }
+        }
+    }
 
-  public static void verify(int a, int b) {
-    boolean exception1 = false, exception2 = false;
-    int result1 = 0, result2 = 0;
-    try {
-      result1 = testIntrinsic(a, b);
-    } catch (ArithmeticException e) {
-      exception1 = true;
+    public static class NonConstantLongTest {
+        public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 };
+        public static java.util.Random rnd = new java.util.Random();
+
+        public static void verify(BinaryLongMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                long rnd1 = rnd.nextLong(), rnd2 = rnd.nextLong();
+                Verify.verifyBinary(rnd1, rnd2, method);
+                Verify.verifyBinary(rnd1, rnd2 + 1, method);
+                Verify.verifyBinary(rnd1 + 1, rnd2, method);
+                Verify.verifyBinary(rnd1 - 1, rnd2, method);
+                Verify.verifyBinary(rnd1, rnd2 - 1, method);
+                Verify.verifyBinary(rnd1 + Long.MAX_VALUE - rnd2, rnd2 + 1, method);
+                Verify.verifyBinary(values[0], values[2], method);
+                Verify.verifyBinary(values[1], values[2], method);
+                Verify.verifyBinary(values[3], 74L, method);
+            }
+        }
+    }
+
+    public static class LoopDependentTest {
+        public static java.util.Random rnd = new java.util.Random();
+
+        public static void verify(BinaryMethod method) {
+            int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
+            runTest(rnd1, rnd2, method);
+        }
+
+        private static void runTest(int rnd1, int rnd2, BinaryMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                Verify.verifyBinary(rnd1 + i, rnd2 + i, method);
+                Verify.verifyBinary(rnd1 + i, rnd2 + (i & 0xff), method);
+                Verify.verifyBinary(rnd1 - i, rnd2 - (i & 0xff), method);
+                Verify.verifyBinary(rnd1 + i + 1, rnd2 + i + 2, method);
+                Verify.verifyBinary(rnd1 + i * 2, rnd2 + i, method);
+            }
+        }
+    }
+
+    public static class ConstantTest {
+        public static void verify(BinaryMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                Verify.verifyBinary(5, 7, method);
+                Verify.verifyBinary(Integer.MAX_VALUE, 1, method);
+                Verify.verifyBinary(Integer.MIN_VALUE, -1, method);
+                Verify.verifyBinary(Integer.MAX_VALUE, -1, method);
+                Verify.verifyBinary(Integer.MIN_VALUE, 1, method);
+                Verify.verifyBinary(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2, method);
+                Verify.verifyBinary(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3, method);
+                Verify.verifyBinary(Integer.MAX_VALUE, Integer.MIN_VALUE, method);
+            }
+        }
+    }
+
+    public static class ConstantLongTest {
+        public static void verify(BinaryLongMethod method) {
+            for (int i = 0; i < 50000; ++i) {
+                Verify.verifyBinary(5, 7, method);
+                Verify.verifyBinary(Long.MAX_VALUE, 1, method);
+                Verify.verifyBinary(Long.MIN_VALUE, -1, method);
+                Verify.verifyBinary(Long.MAX_VALUE, -1, method);
+                Verify.verifyBinary(Long.MIN_VALUE, 1, method);
+                Verify.verifyBinary(Long.MAX_VALUE / 2, Long.MAX_VALUE / 2, method);
+                Verify.verifyBinary(Long.MAX_VALUE / 2, (Long.MAX_VALUE / 2) + 3, method);
+                Verify.verifyBinary(Long.MAX_VALUE, Long.MIN_VALUE, method);
+            }
+        }
+    }
+
+    public static interface BinaryMethod {
+        int safeMethod(int a, int b);
+        int checkMethod(int a, int b);
+        int unchecked(int a, int b);
+        String name();
     }
-    try {
-      result2 = testNonIntrinsic(a, b);
-    } catch (ArithmeticException e) {
-      exception2 = true;
+
+    public static interface UnaryMethod {
+        int safeMethod(int value);
+        int checkMethod(int value);
+        int unchecked(int value);
+        String name();
+    }
+
+    public static interface BinaryLongMethod {
+        long safeMethod(long a, long b);
+        long checkMethod(long a, long b);
+        long unchecked(long a, long b);
+        String name();
+    }
+
+    public static interface UnaryLongMethod {
+        long safeMethod(long value);
+        long checkMethod(long value);
+        long unchecked(long value);
+        String name();
+    }
+
+    public static class UnaryToBinary implements BinaryMethod {
+        private final UnaryMethod method;
+        public UnaryToBinary(UnaryMethod method) {
+            this.method = method;
+        }
+
+        @Override
+        public int safeMethod(int a, int b) {
+            return method.safeMethod(a);
+        }
+
+        @Override
+        public int checkMethod(int a, int b) {
+            return method.checkMethod(a);
+        }
+
+        @Override
+        public int unchecked(int a, int b) {
+            return method.unchecked(a);
+
+        }
+
+        @Override
+        public String name() {
+            return method.name();
+        }
+    }
+
+    public static class UnaryToBinaryLong implements BinaryLongMethod {
+        private final UnaryLongMethod method;
+        public UnaryToBinaryLong(UnaryLongMethod method) {
+            this.method = method;
+        }
+
+        @Override
+        public long safeMethod(long a, long b) {
+            return method.safeMethod(a);
+        }
+
+        @Override
+        public long checkMethod(long a, long b) {
+            return method.checkMethod(a);
+        }
+
+        @Override
+        public long unchecked(long a, long b) {
+            return method.unchecked(a);
+
+        }
+
+        @Override
+        public String name() {
+            return method.name();
+        }
     }
 
-    if (exception1 != exception2) {
-      throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
+
+    public static class AddExactI implements BinaryMethod {
+        @Override
+        public int safeMethod(int x, int y) {
+            int r = x + y;
+            // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+            if (((x ^ r) & (y ^ r)) < 0) {
+                throw new ArithmeticException("integer overflow");
+            }
+            return r;
+
+        }
+
+        @Override
+        public int checkMethod(int a, int b) {
+            return Math.addExact(a, b);
+        }
+
+        @Override
+        public String name() {
+            return "addExact";
+        }
+
+        @Override
+        public int unchecked(int a, int b) {
+            return a + b;
+        }
     }
-    if (result1 != result2) {
-      throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);
+
+    public static class AddExactL implements BinaryLongMethod {
+        @Override
+        public long safeMethod(long x, long y) {
+            long r = x + y;
+            // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+            if (((x ^ r) & (y ^ r)) < 0) {
+                throw new ArithmeticException("integer overflow");
+            }
+            return r;
+
+        }
+
+        @Override
+        public long checkMethod(long a, long b) {
+            return Math.addExact(a, b);
+        }
+
+        @Override
+        public String name() {
+            return "addExactLong";
+        }
+
+        @Override
+        public long unchecked(long a, long b) {
+            return a + b;
+        }
+    }
+
+    public static class MulExactI implements BinaryMethod {
+        @Override
+        public int safeMethod(int x, int y) {
+            long r = (long)x * (long)y;
+            if ((int)r != r) {
+                throw new ArithmeticException("integer overflow");
+            }
+            return (int)r;
+
+        }
+
+        @Override
+        public int checkMethod(int a, int b) {
+            return Math.multiplyExact(a, b);
+        }
+
+        @Override
+        public int unchecked(int a, int b) {
+            return a * b;
+        }
+
+        @Override
+        public String name() {
+            return "multiplyExact";
+        }
     }
-  }
+
+    public static class MulExactL implements BinaryLongMethod {
+        @Override
+        public long safeMethod(long x, long y) {
+            long r = x * y;
+            long ax = Math.abs(x);
+            long ay = Math.abs(y);
+            if (((ax | ay) >>> 31 != 0)) {
+                // Some bits greater than 2^31 that might cause overflow
+                // Check the result using the divide operator
+                // and check for the special case of Long.MIN_VALUE * -1
+                if (((y != 0) && (r / y != x)) ||
+                        (x == Long.MIN_VALUE && y == -1)) {
+                    throw new ArithmeticException("long overflow");
+                }
+            }
+            return r;
+        }
+
+        @Override
+        public long checkMethod(long a, long b) {
+            return Math.multiplyExact(a, b);
+        }
+
+        @Override
+        public long unchecked(long a, long b) {
+            return a * b;
+        }
+
+        @Override
+        public String name() {
+            return "multiplyExact";
+        }
+    }
 
-  public static int testIntrinsic(int a, int b) {
-    return java.lang.Math.addExact(a, b);
-  }
+    public static class NegExactL implements UnaryLongMethod {
+        @Override
+        public long safeMethod(long a) {
+            if (a == Long.MIN_VALUE) {
+                throw new ArithmeticException("long overflow");
+            }
+
+            return -a;
+
+        }
+
+        @Override
+        public long checkMethod(long value) {
+            return Math.negateExact(value);
+        }
+
+        @Override
+        public long unchecked(long value) {
+            return -value;
+        }
+
+        @Override
+        public String name() {
+            return "negateExactLong";
+        }
+    }
+
+    public static class NegExactI implements UnaryMethod {
+        @Override
+        public int safeMethod(int a) {
+            if (a == Integer.MIN_VALUE) {
+                throw new ArithmeticException("integer overflow");
+            }
+
+            return -a;
+
+        }
+
+        @Override
+        public int checkMethod(int value) {
+            return Math.negateExact(value);
+        }
+
+        @Override
+        public int unchecked(int value) {
+            return -value;
+        }
 
-  public static int testNonIntrinsic(int a, int b) {
-    return safeAddExact(a, b);
-  }
+        @Override
+        public String name() {
+            return "negateExact";
+        }
+    }
+
+    public static class SubExactI implements BinaryMethod {
+        @Override
+        public int safeMethod(int x, int y) {
+            int r = x - y;
+            // HD 2-12 Overflow iff the arguments have different signs and
+            // the sign of the result is different than the sign of x
+            if (((x ^ y) & (x ^ r)) < 0) {
+                throw new ArithmeticException("integer overflow");
+            }
+            return r;
+        }
+
+        @Override
+        public int checkMethod(int a, int b) {
+            return Math.subtractExact(a, b);
+        }
+
+        @Override
+        public int unchecked(int a, int b) {
+            return a - b;
+        }
+
+        @Override
+        public String name() {
+            return "subtractExact";
+        }
+    }
+
+    public static class SubExactL implements BinaryLongMethod {
+        @Override
+        public long safeMethod(long x, long y) {
+            long r = x - y;
+            // HD 2-12 Overflow iff the arguments have different signs and
+            // the sign of the result is different than the sign of x
+            if (((x ^ y) & (x ^ r)) < 0) {
+                throw new ArithmeticException("integer overflow");
+            }
+            return r;
+        }
+
+        @Override
+        public long checkMethod(long a, long b) {
+            return Math.subtractExact(a, b);
+        }
+
+        @Override
+        public long unchecked(long a, long b) {
+            return a - b;
+        }
+
+        @Override
+        public String name() {
+            return "subtractExactLong";
+        }
+    }
+
+    static class IncExactL implements UnaryLongMethod {
+        @Override
+        public long safeMethod(long a) {
+            if (a == Long.MAX_VALUE) {
+                throw new ArithmeticException("long overflow");
+            }
+
+            return a + 1L;
+
+        }
+
+        @Override
+        public long checkMethod(long value) {
+            return Math.incrementExact(value);
+        }
+
+        @Override
+        public long unchecked(long value) {
+            return value + 1;
+        }
 
-  // Copied java.lang.Math.addExact to avoid intrinsification
-  public static int safeAddExact(int x, int y) {
-    int r = x + y;
-    // HD 2-12 Overflow iff both arguments have the opposite sign of the result
-    if (((x ^ r) & (y ^ r)) < 0) {
-      throw new ArithmeticException("integer overflow");
+        @Override
+        public String name() {
+            return "incrementExactLong";
+        }
+    }
+
+    static class IncExactI implements UnaryMethod {
+        @Override
+        public int safeMethod(int a) {
+            if (a == Integer.MAX_VALUE) {
+                throw new ArithmeticException("integer overflow");
+            }
+
+            return a + 1;
+        }
+
+        @Override
+        public int checkMethod(int value) {
+            return Math.incrementExact(value);
+        }
+
+        @Override
+        public int unchecked(int value) {
+            return value + 1;
+        }
+
+        @Override
+        public String name() {
+            return "incrementExact";
+        }
     }
-    return r;
-  }
+
+    static class DecExactL implements UnaryLongMethod {
+        @Override
+        public long safeMethod(long a) {
+            if (a == Long.MIN_VALUE) {
+                throw new ArithmeticException("long overflow");
+            }
+
+            return a - 1L;
+        }
+
+        @Override
+        public long checkMethod(long value) {
+            return Math.decrementExact(value);
+        }
+
+        @Override
+        public long unchecked(long value) {
+            return value - 1;
+        }
+
+        @Override
+        public String name() {
+            return "decExactLong";
+        }
+    }
+
+    static class DecExactI implements UnaryMethod {
+        @Override
+        public int safeMethod(int a) {
+            if (a == Integer.MIN_VALUE) {
+                throw new ArithmeticException("integer overflow");
+            }
+
+            return a - 1;
+        }
+
+        @Override
+        public int checkMethod(int value) {
+            return Math.decrementExact(value);
+        }
+
+        @Override
+        public int unchecked(int value) {
+            return value - 1;
+        }
+
+        @Override
+        public String name() {
+            return "decrementExact";
+        }
+    }
+
 }