diff mbox

PR target/79498: Properly store 128-bit constant in large model

Message ID 20170214164249.GA7956@intel.com
State New
Headers show

Commit Message

H.J. Lu Feb. 14, 2017, 4:42 p.m. UTC
When converting TI store with CONST_INT to V1TI store with CONST_VECTOR
in large model, an extra instruction may be needed to load CONST_VECTOR
into a register.  Insert the extra instruction to the right place.

Tested on x86-64.  I am checking in this pre-approved patch.

Thanks.

H.J.
---
gcc/

	PR target/79498
	* config/i386/i386.c (timode_scalar_chain::convert_insn): Insert
	the extra instruction to the right place to store 128-bit constant
	when needed.

gcc/testsuite/

	PR target/79498
	* gcc.target/i386/pr79498.c: New test.
---
 gcc/config/i386/i386.c                  |  5 +++++
 gcc/testsuite/gcc.target/i386/pr79498.c | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr79498.c
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d7dce4b..02287fd 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3956,8 +3956,13 @@  timode_scalar_chain::convert_insn (rtx_insn *insn)
 	  /* Since there are no instructions to store 128-bit constant,
 	     temporary register usage is required.  */
 	  rtx tmp = gen_reg_rtx (V1TImode);
+	  start_sequence ();
 	  src = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec (1, src));
 	  src = validize_mem (force_const_mem (V1TImode, src));
+	  rtx_insn *seq = get_insns ();
+	  end_sequence ();
+	  if (seq)
+	    emit_insn_before (seq, insn);
 	  emit_conversion_insns (gen_rtx_SET (dst, tmp), insn);
 	  dst = tmp;
 	}
diff --git a/gcc/testsuite/gcc.target/i386/pr79498.c b/gcc/testsuite/gcc.target/i386/pr79498.c
new file mode 100644
index 0000000..8f62393
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr79498.c
@@ -0,0 +1,20 @@ 
+/* PR target/79498 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -mno-avx512f -mcmodel=large -Wno-psabi" } */
+
+typedef unsigned U __attribute__ ((vector_size (64)));
+typedef unsigned __int128 V __attribute__ ((vector_size (64)));
+
+static inline V
+bar (U u, U x, V v)
+{
+  v = (V)(U) { 0, ~0 };
+  v[x[0]] <<= u[-63];
+  return v;
+}
+
+V
+foo (U u)
+{
+  return bar (u, (U) {}, (V) {});
+}