RFR: JDK-8298813: [C2] Converting double to float cause a loss of precision and resulting crypto.aes scores fluctuate

SUN Guoyun duke at openjdk.org
Sat Dec 17 01:25:52 UTC 2022


On Thu, 15 Dec 2022 02:52:51 GMT, SUN Guoyun <duke at openjdk.org> wrote:

> Hi all,
> For C2, convert double to float cause a loss of precision,
> 
> <pre><code class="cpp">
> ./chaitin.cpp:221
> _high_frequency_lrg = MIN2(double(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency());
> </code></pre>
> 
> Here, _high_frequency_lrg type is float, so maybe has a loss of precision. when it be used:
> 
> <pre><code class="cpp">
> ./coalesce.cpp:379
> if( lrg._maxfreq >= _phc.high_frequency_lrg() ) {
>    ...
> }
> </code></pre>
> Here, lrg._maxfreq type is double, so _high_frequency_lrg will be convert double again. But now, due to the loss of precision of _high_frequency_lrg, the conditions here may be true or false.
> 
> There are two cases that I tested for SPECjvm2008 crypto.aes.
> case 1:
> <pre><code class="shell">
> //chaitin.cpp:221
> // fcvt.s.d $f0,$f0 #double->float
> d = 16.994714324523816
> f = 16.9947147
> 
> //coalesce.cpp:379
> // fcvt.d.s $f0,$f0 #float->double
> // fcmp.sle.d $fcc2,$f0,$f1
> (gdb) i r fa0
> fa0 {f = 0x0, d = 0x10} {f = -1.08420217e-19, d = 16.994714736938477}
> (gdb) i r fa1
> fa1 {f = 0x0, d = 0x10} {f = -7.68722312e-24, d = 16.994714324523816}
> </code></pre>
> 
> case2:
> <pre><code class="shell">
> //chaitin.cpp:221
> // fcvt.s.d $f0,$f0
> d = 16.996332681816536
> f = 16.9963322
> 
> //coalesce.cpp
> // fcvt.d.s $f0,$f0
> // fcmp.sle.d $fcc2,$f0,$f1
> (gdb) i r fa0
> fa0 {f = 0x0, d = 0x10} {f = -1.08420217e-19, d = 16.996332168579102}
> (gdb) i r fa1
> fa1 {f = 0x0, d = 0x10} {f = -1.73570044e-14, d = 16.996332681816536}
> </code></pre>
> 
> The above two cases result in different block generation(case2 can insert new SpillCopyNodes), and resulting score on cryto.aes is fluctuate.
> 
> This is a patch to fix this problem. Please help review it.
> 
> Thanks,
> Sun Guoyun

OK. you can focus on the instruction generation of function com.sun.crypto.provider.DESCrypt::cipherBlock, sometimes it is 
<pre><code class="shell">
// result 63.4 ops/m
// B5->B112->B55

   B5: #   out( B112 B6 ) <- in( B4 )  Freq: 0.999996
    BRge   T0, A6, B112 #@branchConIU_reg_reg_short  P=0.000001 C=-1.000000
   ...
   B55: #  out( B56 ) <- in( B112 B53 B54 )  Freq: 3.54712e-05
    st_w    T6, [SP + #40]  # spill 9
    CALL,static #@CallStaticJavaDirect  wrapper for: uncommon_trap(reason='range_check' action='make_not_entrant' debug_id='0')
   ILLTRAP   ;#@ShouldNotReachHere
   ...
  B112: # out( B55 ) <- in( B5 )  Freq: 1.01327e-06
  mov    T6, #0 #@loadConI
  JMP    B55 #@jmpDir_short
</code></pre>
and sometimes it is
<pre><code class="shell">
// result: 41.99 ops/m
// B5->B55

     B5: #   out( B55 B6 ) <- in( B4 )  Freq: 0.999996
     mov    A6, #0 #@loadConI
     BRge   T8, T6, B55 #@branchConIU_reg_reg_short  P=0.000001 C=-1.000000

     B55: #  out( B56 ) <- in( B112 B53 B54 )  Freq: 3.54712e-05
             st_w    A6, [SP + #4]  # spill 9
     CALL,static #@CallStaticJavaDirect  wrapper for: uncommon_trap(reason='range_check' action='make_not_entrant' debug_id='0')
     ILLTRAP   ;#@ShouldNotReachHere
</code></pre>

-------------

PR: https://git.openjdk.org/jdk/pull/11685


More information about the hotspot-compiler-dev mailing list