===================================================================
@@ -1662,6 +1662,10 @@ (define_predicate "small_toc_ref"
return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
})
+;; Match a LABEL_REF operand
+(define_predicate "label_ref_operand"
+ (match_code "label_ref"))
+
;; Match the first insn (addis) in fusing the combination of addis and loads to
;; GPR registers on power8.
(define_predicate "fusion_gpr_addis"
===================================================================
@@ -20994,7 +20994,8 @@ rs6000_output_addr_const_extra (FILE *fi
switch (XINT (x, 1))
{
case UNSPEC_TOCREL:
- gcc_checking_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF
+ gcc_checking_assert ((GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF
+ || GET_CODE (XVECEXP (x, 0, 0)) == LABEL_REF)
&& REG_P (XVECEXP (x, 0, 1))
&& REGNO (XVECEXP (x, 0, 1)) == TOC_REGISTER);
output_addr_const (file, XVECEXP (x, 0, 0));
===================================================================
@@ -10219,6 +10219,21 @@ (define_insn_and_split "*tocref<mode>"
[(set (match_dup 0) (high:P (match_dup 1)))
(set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
+;; This pattern exists to allow fwprop to convert the load of the LABEL_REF
+;; address for switches into using ADDIS/ADDI if we can use the TOC
+;; to get the address.
+(define_insn_and_split "*labelref"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
+ (match_operand:DI 1 "label_ref_operand"))]
+ "TARGET_POWERPC64 && TARGET_ELF && TARGET_CMODEL == CMODEL_MEDIUM"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (match_dup 2))]
+{
+ operands[2] = create_TOC_reference (operands[1], NULL_RTX);
+})
+
;; Elf specific ways of loading addresses for non-PIC code.
;; The output of this could be r0, but we make a very strong
;; preference for a base register because it will usually
===================================================================
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { powerpc64le*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-O2 -mcmodel=medium -mcpu=power8" } */
+
+/* Test that we don't load the label address when creating a switch table on
+ PowerPC LE systems using the medium code model. */
+
+unsigned long test (unsigned long a, unsigned long b, unsigned long c)
+{
+ switch (a)
+ {
+ default: return a+b;
+ case 10: return a-b;
+ case 11: return a*b;
+ case 12: return a/b;
+ case 13: return a<<b;
+ case 14: return a>>b;
+ case 15: return a | b;
+ case 16: return a & b;
+ case 17: return a ^ b;
+ case 18: return a & ~b;
+ case 19: return a | ~b;
+ case 20: return a ^ ~b;
+ }
+}
+
+/* { dg-final { scan-assembler-not {\mld\M} } } */
+/* { dg-final { scan-assembler {\maddis .*@toc@ha\M} } } */
+/* { dg-final { scan-assembler {\maddi .*@toc@l\M} } } */