diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index 4020b27..90ada7d 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -1749,6 +1749,19 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg) } } +/* Helper function to convert immediate constant X to V1TImode. */ +static rtx +timode_convert_cst (rtx x) +{ + /* Prefer all ones vector in case of -1. */ + if (constm1_operand (x, TImode)) + return CONSTM1_RTX (V1TImode); + + rtx *v = XALLOCAVEC (rtx, 1); + v[0] = x; + return gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec_v (1, v)); +} + /* Convert operand OP in INSN from TImode to V1TImode. */ void @@ -1775,18 +1788,8 @@ timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } else if (CONST_SCALAR_INT_P (*op)) { - rtx vec_cst; rtx tmp = gen_reg_rtx (V1TImode); - - /* Prefer all ones vector in case of -1. */ - if (constm1_operand (*op, TImode)) - vec_cst = CONSTM1_RTX (V1TImode); - else - { - rtx *v = XALLOCAVEC (rtx, 1); - v[0] = *op; - vec_cst = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec_v (1, v)); - } + rtx vec_cst = timode_convert_cst (*op); if (!standard_sse_constant_p (vec_cst, V1TImode)) { @@ -1830,12 +1833,28 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) tmp = find_reg_equal_equiv_note (insn); if (tmp) { - if (GET_MODE (XEXP (tmp, 0)) == TImode) - PUT_MODE (XEXP (tmp, 0), V1TImode); - else if (CONST_SCALAR_INT_P (XEXP (tmp, 0))) - XEXP (tmp, 0) - = gen_rtx_CONST_VECTOR (V1TImode, - gen_rtvec (1, XEXP (tmp, 0))); + rtx expr = XEXP (tmp, 0); + if (GET_MODE (expr) == TImode) + { + PUT_MODE (expr, V1TImode); + switch (GET_CODE (expr)) + { + case PLUS: + case MINUS: + case MULT: + case AND: + case IOR: + case XOR: + if (CONST_SCALAR_INT_P (XEXP (expr, 1))) + XEXP (expr, 1) = timode_convert_cst (XEXP (expr, 1)); + break; + + default: + break; + } + } + else if (CONST_SCALAR_INT_P (expr)) + XEXP (tmp, 0) = timode_convert_cst (expr); } } break; @@ -1876,7 +1895,7 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) } else { - src = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec (1, src)); + src = timode_convert_cst (src); src = validize_mem (force_const_mem (V1TImode, src)); use_move = MEM_P (dst); } diff --git a/gcc/testsuite/gcc.target/i386/pr113690.c b/gcc/testsuite/gcc.target/i386/pr113690.c new file mode 100644 index 0000000..23a1108 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr113690.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fno-dce -fno-forward-propagate -fno-split-wide-types -funroll-loops" } */ +int i; +__attribute__((__vector_size__(64))) __int128 v; + +void +foo(void) +{ + v <<= 127; + __builtin_mul_overflow(0, i, &v[3]); + v *= 6; +}