https://gcc.gnu.org/g:34285402005b19f7ac2d069e4f5e161e86318b3b
commit r16-6308-g34285402005b19f7ac2d069e4f5e161e86318b3b Author: Jakub Jelinek <[email protected]> Date: Sat Dec 20 11:58:25 2025 +0100 i386: Fix up expansion of 2 keylocker and one user_msr builtin [PR123217] target can be especially at -O0 a MEM, not just a REG, and most of the ix86_expand_builtin spots which use target and can't support MEM destinations deal with it properly, except these 3 spots don't. Fixed thusly, when we change target to a new pseudo, the caller will take care of storing that pseudo into the MEM, and this is the solution other spots with similar requirements use in the function. 2025-12-20 Jakub Jelinek <[email protected]> PR target/123217 * config/i386/i386-expand.cc (ix86_expand_builtin) <case IX86_BUILTIN_ENCODEKEY128U32, case IX86_BUILTIN_ENCODEKEY256U32, case IX86_BUILTIN_URDMSR>: Set target to a new pseudo even if it is non-NULL but doesn't satisfy register_operand predicate. * gcc.target/i386/keylocker-pr123217.c: New test. * gcc.target/i386/user_msr-pr123217.c: New test. Diff: --- gcc/config/i386/i386-expand.cc | 6 +++--- gcc/testsuite/gcc.target/i386/keylocker-pr123217.c | 13 +++++++++++++ gcc/testsuite/gcc.target/i386/user_msr-pr123217.c | 10 ++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 438fa4e4b6af..ddce947d1a8b 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -15131,7 +15131,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, for (i = 0; i < 3; i++) xmm_regs[i] = gen_rtx_REG (V2DImode, GET_SSE_REGNO (i)); - if (target == 0) + if (target == 0 || !register_operand (target, SImode)) target = gen_reg_rtx (SImode); emit_insn (gen_encodekey128u32 (target, op0)); @@ -15174,7 +15174,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, for (i = 0; i < 4; i++) xmm_regs[i] = gen_rtx_REG (V2DImode, GET_SSE_REGNO (i)); - if (target == 0) + if (target == 0 || !register_operand (target, SImode)) target = gen_reg_rtx (SImode); emit_insn (gen_encodekey256u32 (target, op0)); @@ -15323,7 +15323,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, } else { - if (target == 0) + if (target == 0 || !register_operand (target, DImode)) target = gen_reg_rtx (DImode); icode = CODE_FOR_urdmsr; op1 = op0; diff --git a/gcc/testsuite/gcc.target/i386/keylocker-pr123217.c b/gcc/testsuite/gcc.target/i386/keylocker-pr123217.c new file mode 100644 index 000000000000..27b89970ae81 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/keylocker-pr123217.c @@ -0,0 +1,13 @@ +/* PR target/123217 */ +/* { dg-do compile } */ +/* { dg-options "-mkl -O0" } */ + +__attribute__((__vector_size__(16))) long long v, w; + +unsigned +foo (void *p, void *q) +{ + unsigned x = __builtin_ia32_encodekey128_u32 (0U, v, p); + unsigned y = __builtin_ia32_encodekey256_u32 (0U, v, w, q); + return x + y; +} diff --git a/gcc/testsuite/gcc.target/i386/user_msr-pr123217.c b/gcc/testsuite/gcc.target/i386/user_msr-pr123217.c new file mode 100644 index 000000000000..115211334db7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/user_msr-pr123217.c @@ -0,0 +1,10 @@ +/* PR target/123217 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-musermsr -O0" } */ + +unsigned long long +foo (unsigned long long x) +{ + unsigned long long y = __builtin_ia32_urdmsr (x); + return y; +}
