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

Richard Reingruber rrich at openjdk.org
Thu Jan 29 11:23:41 UTC 2026


On Thu, 29 Jan 2026 09:46:49 GMT, Martin Doerr <mdoerr 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?
>> 
>>> Btw. what the Spec suggests also seems to use the wrong order:
>> 
>> Where can that be found?
>
>> > 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?

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

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


More information about the hotspot-compiler-dev mailing list