[PATCH, i386]: Fix and improve a couple of builtin expansions
Uros Bizjak
ubizjak@gmail.com
Thu May 10 21:16:00 GMT 2018
Hello!
The missing return in _xgetbv is a bug and will be backported to
release branches.
2018-05-10 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (ix86_expand_builtin) <case IX86_BUILTIN_RDPID>:
Generate SImode target register for null target.
<case IX86_BUILTIN_XGETBV>: Ditto.
<case IX86_BUILTIN_XSETBV>: Optimize LSHIFTRT generation.
* config/i386/xsaveintrin.h (_xgetbv): Add missing return.
testsuite/ChangeLog:
2018-05-10 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/xgetsetbv.c: Check also variable arguments.
Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
Committed to mainline SVN.
Uros.
-------------- next part --------------
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 260116)
+++ config/i386/i386.c (working copy)
@@ -37085,7 +37085,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
case IX86_BUILTIN_RDPID:
- op0 = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
+ op0 = gen_reg_rtx (word_mode);
if (TARGET_64BIT)
{
@@ -37094,18 +37094,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
}
else
insn = gen_rdpid (op0);
+
emit_insn (insn);
- if (target == 0)
- {
- /* mode is VOIDmode if __builtin_rdpid has been called
- without lhs. */
- if (mode == VOIDmode)
- return target;
- target = gen_reg_rtx (mode);
- }
+ if (target == 0
+ || !register_operand (target, SImode))
+ target = gen_reg_rtx (SImode);
+
emit_move_insn (target, op0);
return target;
+
case IX86_BUILTIN_RDPMC:
case IX86_BUILTIN_RDTSC:
case IX86_BUILTIN_RDTSCP:
@@ -37164,14 +37162,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
emit_move_insn (gen_rtx_MEM (SImode, op4), op2);
}
- if (target == 0)
- {
- /* mode is VOIDmode if __builtin_rd* has been called
- without lhs. */
- if (mode == VOIDmode)
- return target;
- target = gen_reg_rtx (mode);
- }
+ if (target == 0
+ || !register_operand (target, DImode))
+ target = gen_reg_rtx (DImode);
if (TARGET_64BIT)
{
@@ -37260,25 +37253,23 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub
if (!REG_P (op0))
op0 = copy_to_mode_reg (SImode, op0);
+ op1 = force_reg (DImode, op1);
+
if (TARGET_64BIT)
{
op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
NULL, 1, OPTAB_DIRECT);
+ icode = CODE_FOR_xsetbv_rex64;
+
op2 = gen_lowpart (SImode, op2);
op1 = gen_lowpart (SImode, op1);
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (SImode, op1);
- if (!REG_P (op2))
- op2 = copy_to_mode_reg (SImode, op2);
- icode = CODE_FOR_xsetbv_rex64;
pat = GEN_FCN (icode) (op0, op1, op2);
}
else
{
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (DImode, op1);
icode = CODE_FOR_xsetbv;
+
pat = GEN_FCN (icode) (op0, op1);
}
if (pat)
Index: config/i386/xsaveintrin.h
===================================================================
--- config/i386/xsaveintrin.h (revision 260116)
+++ config/i386/xsaveintrin.h (working copy)
@@ -59,7 +59,7 @@ extern __inline long long
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_xgetbv (unsigned int __A)
{
- __builtin_ia32_xgetbv (__A);
+ return __builtin_ia32_xgetbv (__A);
}
#ifdef __x86_64__
Index: testsuite/gcc.target/i386/xgetsetbv.c
===================================================================
--- testsuite/gcc.target/i386/xgetsetbv.c (revision 260116)
+++ testsuite/gcc.target/i386/xgetsetbv.c (working copy)
@@ -1,13 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mxsave" } */
-/* { dg-final { scan-assembler "xgetbv" } } */
-/* { dg-final { scan-assembler "xsetbv" } } */
+/* { dg-final { scan-assembler-times "xgetbv" 3 } } */
+/* { dg-final { scan-assembler-times "xsetbv" 3 } } */
#include <x86intrin.h>
-unsigned int
-xgetsetbv (void)
+unsigned long long
+foo (unsigned x, unsigned y)
{
+ _xsetbv (x, y);
+ return _xgetbv (x);
+}
+
+unsigned long long
+bar (unsigned x, unsigned long long y)
+{
+ _xsetbv (x, y);
+ return _xgetbv (x);
+}
+
+unsigned long long
+baz (void)
+{
_xsetbv (0, 0);
return _xgetbv (0);
}
More information about the Gcc-patches
mailing list