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