https://gcc.gnu.org/g:182346a920cc0782f7095f043ddb1c3689330ecc
commit 182346a920cc0782f7095f043ddb1c3689330ecc Author: Michael Meissner <[email protected]> Date: Fri Oct 3 22:16:35 2025 -0400 Add 16-bit floating point abs; Remove expand/truncate optimization. 2025-10-03 Michael Meissner <[email protected]> gcc/ * config/rs6000/float16.md (xor<mode>3): Favor vector registers over GPRs. (no_extend_trunc_<SFDF:mode>_<FP16_HW:mode>): Delete. (abs<mode>2): New insn. (andc<mode>3): Likewise. (nabs<mode>2): Likewise. (ior<mode>3): Likewise. Diff: --- gcc/config/rs6000/float16.md | 95 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md index f30f0fbc6b64..982aeafb74d1 100644 --- a/gcc/config/rs6000/float16.md +++ b/gcc/config/rs6000/float16.md @@ -425,7 +425,7 @@ ;; power10, since we can easily load up -0.0 via XXSPLTIW. (define_insn_and_split "neg<mode>2" - [(set (match_operand:FP16 0 "register_operand" "=wa,wr") + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") (neg:FP16 (match_operand:FP16 1 "register_operand" "wa,wr"))) (clobber (match_scratch:FP16 2 "=&wa,&r"))] "TARGET_POWER10 && TARGET_PREFIXED" @@ -451,8 +451,8 @@ ;; XOR used to negate a 16-bit floating point type -(define_insn "xor<mode>3" - [(set (match_operand:FP16 0 "register_operand" "=wa,wr") +(define_insn "*xor<mode>3" + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") (xor:FP16 (match_operand:FP16 1 "register_operand" "wa,wr") (match_operand:FP16 2 "register_operand" "wa,wr")))] "TARGET_POWER10 && TARGET_PREFIXED" @@ -461,16 +461,85 @@ xor %0,%1,%2" [(set_attr "type" "veclogical,integer")]) - -;; If the user used -Ofast, eliminate back to back extend/trunc -;; operations +;; 16-bit floating point absolute value -(define_insn_and_split "*no_extend_trunc_<SFDF:mode>_<FP16_HW:mode>" - [(set (match_operand:FP16_HW 0 "vsx_register_operand" "=wa") - (float_truncate:FP16_HW - (float_extend:SFDF - (match_operand:FP16_HW 1 "vsx_register_operand" "wa"))))] - "optimize_fast" +(define_insn_and_split "abs<mode>2" + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") + (abs:FP16 (match_operand:FP16 1 "register_operand" "wa,wr"))) + (clobber (match_scratch:FP16 2 "=&wa,&r"))] + "TARGET_POWER10 && TARGET_PREFIXED" + "#" + "&& 1" + [(set (match_dup 2) + (match_dup 3)) + (set (match_dup 0) + (and:FP16 (match_dup 1) + (not:FP16 (match_dup 2))))] +{ + REAL_VALUE_TYPE dconst; + + gcc_assert (real_from_string (&dconst, "-0.0") == 0); + + if (GET_CODE (operands[2]) == SCRATCH) + operands[2] = gen_reg_rtx (<MODE>mode); + + operands[3] = const_double_from_real_value (dconst, <MODE>mode); +} + [(set_attr "type" "veclogical,integer") + (set_attr "length" "16")]) + +;; ANDC used to clear the sign bit of a 16-bit floating point type +;; for absolute value. + +(define_insn "*andc<mode>3" + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") + (and:FP16 (match_operand:FP16 1 "register_operand" "wa,wr") + (not:FP16 + (match_operand:FP16 2 "register_operand" "wa,wr"))))] + "TARGET_POWER10 && TARGET_PREFIXED" + "@ + xxlandc %x0,%x1,%x2 + andc %0,%1,%2" + [(set_attr "type" "veclogical,integer")]) + +;; 16-bit negative floating point absolute value + +(define_insn_and_split "*nabs<mode>2" + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") + (neg:FP16 + (abs:FP16 + (match_operand:FP16 1 "register_operand" "wa,wr")))) + (clobber (match_scratch:FP16 2 "=&wa,&r"))] + "TARGET_POWER10 && TARGET_PREFIXED" "#" "&& 1" - [(set (match_dup 0) (match_dup 1))]) + [(set (match_dup 2) + (match_dup 3)) + (set (match_dup 0) + (ior:FP16 (match_dup 1) + (match_dup 2)))] +{ + REAL_VALUE_TYPE dconst; + + gcc_assert (real_from_string (&dconst, "-0.0") == 0); + + if (GET_CODE (operands[2]) == SCRATCH) + operands[2] = gen_reg_rtx (<MODE>mode); + + operands[3] = const_double_from_real_value (dconst, <MODE>mode); +} + [(set_attr "type" "veclogical,integer") + (set_attr "length" "16")]) + +;; OR used to set the sign bit of a 16-bit floating point type +;; for negative absolute value. + +(define_insn "*ior<mode>3" + [(set (match_operand:FP16 0 "register_operand" "=wa,?wr") + (ior:FP16 (match_operand:FP16 1 "register_operand" "wa,wr") + (match_operand:FP16 2 "register_operand" "wa,wr")))] + "TARGET_POWER10 && TARGET_PREFIXED" + "@ + xxlor %x0,%x1,%x2 + or %0,%1,%2" + [(set_attr "type" "veclogical,integer")])
