@@ -10240,6 +10240,25 @@ rs6000_emit_set_const (rtx dest, rtx source)
c = sext_hwi (c, 32);
emit_move_insn (lo, GEN_INT (c));
}
+
+ /* Use base_reg_operand to avoid spliting "r0=xxx" to "r0=[r0+off]"
+ after RA when reusing the DEST register to build the value. */
+ else if ((can_create_pseudo_p () || base_reg_operand (dest, mode))
+ && num_insns_constant (source, mode)
+ > rs6000_min_insns_constant_in_pool
+ && TARGET_64BIT)
+ {
+ rtx sym = force_const_mem (mode, source);
+ if (TARGET_TOC && SYMBOL_REF_P (XEXP (sym, 0))
+ && use_toc_relative_ref (XEXP (sym, 0), mode))
+ {
+ rtx toc = create_TOC_reference (XEXP (sym, 0), dest);
+ sym = gen_const_mem (mode, toc);
+ set_mem_alias_set (sym, get_TOC_alias_set ());
+ }
+
+ emit_move_insn (dest, sym);
+ }
else
rs6000_emit_set_long_const (dest, c);
break;
@@ -679,3 +679,8 @@ default value is 4.
Target Undocumented Joined UInteger Var(rs6000_vect_unroll_reduc_threshold) Init(1) Param
When reduction factor computed for a loop exceeds the threshold specified by
this parameter, prefer to unroll this loop. The default value is 1.
+
+-param=rs6000-min-insns-constant-in-pool=
+Target Undocumented Joined UInteger Var(rs6000_min_insns_constant_in_pool) Init(2) IntegerRange(2, 5) Param
+The minimum instruction number of building a constant to force loading it from
+the constant pool.
\ No newline at end of file
@@ -1,5 +1,5 @@
/* { dg-do compile { target has_arch_ppc64 } } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fdump-rtl-final" } */
#define C1 0x2351847027482577ULL
#define C2 0x2351847027482578ULL
@@ -17,4 +17,5 @@ void __attribute__ ((noinline)) foo1 (long long *a, long long b)
*a++ = C2;
}
-/* { dg-final { scan-assembler-times {\maddi\M} 2 } } */
+/* { dg-final { scan-rtl-dump-times {\madddi3\M} 2 "final" } } */
+
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2 -mno-prefixed -save-temps" } */
+/* { dg-options "-O2 -mno-prefixed --param=rs6000-min-insns-constant-in-pool=5 -save-temps" } */
/* { dg-require-effective-target has_arch_ppc64 } */
/* { dg-final { scan-assembler-times {\mlis\M} 4 } } */
@@ -1,5 +1,5 @@
/* PR target/106550 */
-/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 --param=rs6000-min-insns-constant-in-pool=3" } */
/* { dg-require-effective-target has_arch_ppc64 } */
void
@@ -1,7 +1,7 @@
/* PR target/106550 */
/* { dg-require-effective-target power10_ok } */
/* { dg-require-effective-target has_arch_ppc64 } */
-/* { dg-options "-O2 -mdejagnu-cpu=power10 -fdisable-rtl-split1" } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -fdisable-rtl-split1 --param=rs6000-min-insns-constant-in-pool=5" } */
/* force the constant splitter run after RA: -fdisable-rtl-split1. */
void
new file mode 100644
@@ -0,0 +1,11 @@
+/* Check loading constant from memory pool. */
+/* { dg-options "-O2 -mpowerpc64" } */
+
+void
+foo (unsigned long long *a)
+{
+ *a++ = 0x2351847027482577ULL;
+}
+
+/* { dg-final { scan-assembler-times {\mp?ld\M} 1 { target { lp64 } } } } */
+
@@ -25,4 +25,7 @@ test3 (void)
return ((__int128)0xdeadbeefcafebabe << 64) | 0xfacefeedbaaaaaad;
}
-/* { dg-final { scan-assembler-not {\mld\M} } } */
+/* test3 is using "ld" to load the value to r3 and r4. So there are 2 'ld's
+ test0, test1 and test2 are using "li", then check 6 'li's. */
+/* { dg-final { scan-assembler-times {\mp?ld\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mli\M} 6 } } */
@@ -1,6 +1,6 @@
/* PR target/93012 */
/* { dg-do compile { target lp64 } } */
-/* { dg-options "-O2 -std=c99" } */
+/* { dg-options "-O2 -std=c99 --param=rs6000-min-insns-constant-in-pool=5" } */
unsigned long long msk66() { return 0x6666666666666666ULL; }
unsigned long long mskih() { return 0xabcd1234abcd1234ULL; }