https://gcc.gnu.org/g:474322266e69039e69a0288fe5955439f9709671
commit 474322266e69039e69a0288fe5955439f9709671 Author: Michael Meissner <meiss...@linux.ibm.com> Date: Tue Apr 9 15:37:44 2024 -0400 Make sure wide immediate fusion does not generate illegal instructions. 2024-04-09 Michael Meissner <meiss...@linux.ibm.com> gcc/ * config/rs6000/fusion.md: Regenerate. * config/rs6000/genfusion.md (gen_wide_immediate): Fix code. * config/rs6000/predicates.md (u32bit_cint_2_insns_operand): New predicate. Diff: --- gcc/config/rs6000/fusion.md | 11 ++++++++--- gcc/config/rs6000/genfusion.pl | 9 +++++++-- gcc/config/rs6000/predicates.md | 9 +++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index 45819627df6..5feedf83cad 100644 --- a/gcc/config/rs6000/fusion.md +++ b/gcc/config/rs6000/fusion.md @@ -3061,7 +3061,12 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") (iorxor:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "non_logical_cint_operand" "n")))] - "(TARGET_P10_FUSION)" - "<IORXOR_OP>i %0,%1,%w2\;<IORXOR_OP>is %0,%0,%v2" + (match_operand:DI 2 "u32bit_cint_2_insns_operand" "n")))] + "(TARGET_P10_FUSION)" +{ + HOST_WIDE_INT value = INTVAL (operands[2]); + operands[3] = GEN_INT (value & 0xffff); + operands[4] = GEN_INT ((value >> 16) & 0xffff); + return "<IORXOR_OP>i %0,%1,%3\;<IORXOR_OP>is %0,%0,%4"; +} [(set_attr "length" "8")]) diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl index d059de8afc9..b6f1016b830 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -376,9 +376,14 @@ sub gen_wide_immediate [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") (iorxor:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "non_logical_cint_operand" "n")))] + (match_operand:DI 2 "u32bit_cint_2_insns_operand" "n")))] "(TARGET_P10_FUSION)" - "<IORXOR_OP>i %0,%1,%w2\\;<IORXOR_OP>is %0,%0,%v2" +{ + HOST_WIDE_INT value = INTVAL (operands[2]); + operands[3] = GEN_INT (value & 0xffff); + operands[4] = GEN_INT ((value >> 16) & 0xffff); + return "<IORXOR_OP>i %0,%1,%3\\;<IORXOR_OP>is %0,%0,%4"; +} [(set_attr "length" "8")]) EOF } diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index d23ce9a77a3..83f368b2916 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -282,6 +282,15 @@ (and (match_code "const_int") (match_test "(0x80000000 + UINTVAL (op)) >> 32 == 0"))) +;; Return 1 if op is a 32-bit unsigned constant where the upper 16-bits is +;; non-zero along with the lower 16-bits that needs two instructions (ORI/ORIS +;; or XORI/XORIS to do the operation). +(define_predicate "u32bit_cint_2_insns_operand" + (and (match_code "const_int") + (match_test "(INTVAL (op) >> 32) == 0") + (match_test "(INTVAL (op) & 0xffff) != 0") + (match_test "(INTVAL (op) & 0xffff0000) != 0"))) + ;; Return 1 if op is a constant 32-bit unsigned (define_predicate "c32bit_cint_operand" (and (match_code "const_int")