RFR: 8375536: PPC64: Implement special MachNodes for floating point CMove [v2]

Martin Doerr mdoerr at openjdk.org
Thu Jan 29 11:57:49 UTC 2026


On Thu, 29 Jan 2026 11:21:04 GMT, Richard Reingruber <rrich at openjdk.org> wrote:

>>> > Please note that C2 generates code which is equivalent to your C version:
>>> 
>>> Could you please provide the Java source code for that?
>> 
>> 
>> class test {
>>   static double cmovf_eq(double op1, double op2, double src1, double src2) {
>>     return op1 == op2 ? src1 : src2;
>>   }
>> 
>>   static void main(String[] args) {
>>     double result = 0.0;
>>     for (int i = 0; i < 100_000; ++i) {
>>       result += cmovf_eq((double) (i / 2), (double) ((i + 1) / 2), 1.0, 2.0);
>>     }
>>     System.out.println("result = " + result);
>>   }
>> }
>> 
>> 
>>> > Btw. what the Spec suggests also seems to use the wrong order:
>>> 
>>> Where can that be found?
>> 
>> PowerISA™ Version3.1C
>
> Thanks, I was looking at 3.1B which doesn't have the programming note.
> 
> Thanks also for the example. The trick to get the cmove is that the condition mustn't be true or false all the time.
> 
> We should also have OptoAssembly that shows the condition and the registers.
> For testing I've added
> 
>   format %{ "cmovD_cmpD  $dst, $op1 $cop $op2, $src1, $src2\n\t" %}
> 
> My testmethod
> 
>     static double dontinline_cmovf(double op1, double op2, double src1, double src2) {
>         return op1 == op2 ? src1 : src2;
>     }
> 
> produces this OptoAssembly
> 
> ============================= C2-compiled nmethod ==============================
> #r090 F0:F0   : parm 0: double <- note: register names are incorrect
> #r088 F0:F0   : parm 2: double
> #r086 F0:F0   : parm 4: double
> #r084 F0:F0   : parm 6: double
> #r283 R1+76: old out preserve
> #r282 R1+72: old out preserve
> // ...
> 028     cmovD_cmpD  F1, F1 ne F2, F3, F4
> 
> testing...
> 
>         res = dontinline_cmovf(1d, 2d, 3d, 4d);
>         System.out.println(op1 + " == " + op2 + " ? " + src1 + " : " + src2);
>         System.out.println("-> " + res);
> 
> 1.0 == 2.0 ? 3.0 : 4.0
> -> 4.0
> 
> Very weired: the condition `==` is flipped to `ne` but `src1` and `src2` are not swapped since 4.0 is in `F4` which is `src2` according to the OptoAssembly above.
> 
> I would have expected
> 
> 
> 028     cmovD_cmpD  F1, F1 ne F2, F4, F3
> 
> Is there an explanation?

The condition is adjusted for `CMove` with match rules like `match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));`. If the condition is `false`, the value `dst` is kept. If the condition is `true`, the value `src` is used. So, the comment for PPC64 should actually say "dst = (op1 cmp(cc) op2) ? src2 : src1;".

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

PR Review Comment: https://git.openjdk.org/jdk/pull/29281#discussion_r2741276653


More information about the hotspot-compiler-dev mailing list