[aarch64] : fix unrecognizable insn for ldr got in ilp32 tiny

Message ID AM6PR08MB355944B67C30FD177B4A7F8FE0ED0@AM6PR08MB3559.eurprd08.prod.outlook.com
State New
Headers show
Series
  • [aarch64] : fix unrecognizable insn for ldr got in ilp32 tiny
Related show

Commit Message

Sylvia Taylor June 11, 2019, 1:25 p.m.
Greetings,

This patch addresses a bug in ldr GOT for mcmodel=tiny in
which this instruction is not generated for ilp32 modes.

Defined 2 new patterns for ldr_got_tiny. Added additional
checks to use the appropriate rtl pattern for any of the modes.

Examples of previously unrecognized instructions:
ldr    x1, :got:_ZTIi    // [c=4 l=4]  ldr_got_tiny_si
ldr    x0, :got:global   // [c=4 l=4]  ldr_got_tiny_sidi

Bootstrapped and tested on aarch64-none-linux-gnu.
Bug fix tested with aarch64-none-elf-g++ -mabi=ilp32 -mcmodel=tiny -fpic.

The existing test now fixed is: testsuite/g++.dg/torture/stackalign/throw-1.C

Ok for trunk? If yes, I don't have any commit rights,
so can someone please commit it on my behalf.

Cheers,
Syl

gcc/ChangeLog:

2019-06-11  Sylvia Taylor  <sylvia.taylor@arm.com>

	* config/aarch64/aarch64.c
	(aarch64_load_symref_appropriately): Change SYMBOL_TINY_GOT.
	* config/aarch64/aarch64.md
	(ldr_got_tiny): Change to ldr_got_tiny_di.
	(ldr_got_tiny_si): New pattern.
	(ldr_got_tiny_sidi): New pattern.

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b38505b0872688634b2d3f625ab8d313e89cfca0..26a8f91b4af53eb2301f27f82a164174c6ef7774 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2251,8 +2251,26 @@  aarch64_load_symref_appropriately (rtx dest, rtx imm,
       }
 
     case SYMBOL_TINY_GOT:
-      emit_insn (gen_ldr_got_tiny (dest, imm));
-      return;
+      {
+	machine_mode mode = GET_MODE (dest);
+
+	if (mode == ptr_mode)
+	  {
+	    if (mode == DImode)
+	      emit_insn (gen_ldr_got_tiny_di (dest, imm));
+	    else
+	      /* TARGET_ILP32.  */
+	      emit_insn (gen_ldr_got_tiny_si (dest, imm));
+	  }
+	else
+	  {
+	    /* TARGET_ILP32.  */
+	    gcc_assert (mode == Pmode);
+	    emit_insn (gen_ldr_got_tiny_sidi (dest, imm));
+	  }
+
+	return;
+      }
 
     case SYMBOL_TINY_TLSIE:
       {
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index ff83974aeb0b1bf46415c29ba47ada74a79d7586..d594a81ed42bf2e5af4c5db659eb43c2b33ccad7 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6469,15 +6469,37 @@ 
   [(set_attr "type" "load_4")]
 )
 
-(define_insn "ldr_got_tiny"
+(define_insn "ldr_got_tiny_di"
   [(set (match_operand:DI 0 "register_operand" "=r")
-	(unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
-		   UNSPEC_GOTTINYPIC))]
+	(unspec:DI
+	  [(match_operand:DI 1 "aarch64_valid_symref" "S")]
+	UNSPEC_GOTTINYPIC))]
   ""
   "ldr\\t%0, %L1"
   [(set_attr "type" "load_8")]
 )
 
+(define_insn "ldr_got_tiny_si"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI
+	  [(match_operand:SI 1 "aarch64_valid_symref" "S")]
+	UNSPEC_GOTTINYPIC))]
+  "TARGET_ILP32"
+  "ldr\\t%0, %L1"
+  [(set_attr "type" "load_4")]
+)
+
+(define_insn "ldr_got_tiny_sidi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI
+	  (unspec:SI
+	    [(match_operand:DI 1 "aarch64_valid_symref" "S")]
+	  UNSPEC_GOTTINYPIC)))]
+  "TARGET_ILP32"
+  "ldr\\t%0, %L1"
+  [(set_attr "type" "load_4")]
+)
+
 (define_insn "aarch64_load_tp_hard"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(unspec:DI [(const_int 0)] UNSPEC_TLS))]