Bug 83111 - [7/8 Regression][sh] stack smashing detected in gen_udivsi3
Summary: [7/8 Regression][sh] stack smashing detected in gen_udivsi3
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 7.3
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2017-11-22 16:44 UTC by Tom de Vries
Modified: 2017-11-23 14:11 UTC (History)
0 users

See Also:
Host:
Target: sh
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-11-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2017-11-22 16:44:24 UTC
During a sh-linux-gnu build, I run into a build breaker:
...
sh/build/./gcc/xgcc -Bsh/build/./gcc/ -Bsh/install/sh-linux-gnu/bin/ -Bsh/install/sh-linux-gnu/lib/ -isystem sh/install/sh-linux-gnu/include -isystem sh/install/sh-linux-gnu/sys-include    -g -O2 -mb -O2  -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -fpic -DNO_FPSCR_VALUES -w -Wno-sync-nand -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -fpic -DNO_FPSCR_VALUES -w -Wno-sync-nand -I. -I. -I../../.././gcc -I/src/libgcc -I/src/libgcc/. -I/src/libgcc/../gcc -I/src/libgcc/../include    -o _moddi3.o -MT _moddi3.o -MD -MP -MF _moddi3.dep -DL_moddi3 -c /src/libgcc/libgcc2.c   -fexceptions -fnon-call-exceptions -fvisibility=hidden -DHIDE_EXPORTS
*** stack smashing detected ***: sh/build/./gcc/cc1 terminated
during RTL pass: expand
/src/libgcc/libgcc2.c: In function ‘__moddi3’:
/src/libgcc/libgcc2.c:1092:9: internal compiler error: Aborted
d0 = 1 / d0; /* Divide intentionally by zero.  */
~~~^~~~~~~~
0x109919b crash_signal
/src/gcc/toplev.c:325
0x175dbbe gen_udivsi3(rtx_def*, rtx_def*, rtx_def*)
sh/build/gcc/insn-emit.c:12919
0xdd4687 insn_gen_fn::operator()(rtx_def*, rtx_def*, rtx_def*) const
/src/gcc/recog.h:302
0xe85b15 maybe_gen_insn(insn_code, unsigned int, expand_operand*)
/src/gcc/optabs.c:7103
0xe733e3 expand_binop_directly
/src/gcc/optabs.c:1071
0xe738b2 expand_binop(machine_mode, optab_tag, rtx_def*, rtx_def*, rtx_def*, int, optab_methods)
/src/gcc/optabs.c:1159
0xe75ead sign_expand_binop(machine_mode, optab_tag, optab_tag, rtx_def*, rtx_def*, rtx_def*, int, optab_methods)
/src/gcc/optabs.c:1879
0xb097aa expand_divmod(int, tree_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, int)
/src/gcc/expmed.c:5091
0xb362c8 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier)
/src/gcc/expr.c:8844
0x9747a9 expand_gimple_stmt_1
/src/gcc/cfgexpand.c:3713
0x974ad1 expand_gimple_stmt
/src/gcc/cfgexpand.c:3773
0x97e208 expand_gimple_basic_block
/src/gcc/cfgexpand.c:5774
0x97fa5e execute
/src/gcc/cfgexpand.c:6375
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
...
Comment 1 Tom de Vries 2017-11-22 16:47:31 UTC
Looking at insn-emit.c, we see:
...
/* src/gcc/config/sh/sh.md:2273 */
rtx
gen_udivsi3 (rtx operand0,
        rtx operand1,
        rtx operand2)
{
  rtx_insn *_val = 0;
  start_sequence ();
  {
    rtx operands[3];
    operands[0] = operand0;
    operands[1] = operand1;
    operands[2] = operand2;
#define FAIL return (end_sequence (), _val)
#define DONE return (_val = get_insns (),end_sequence (), _val)
// #line 2278 "src/gcc/config/sh/sh.md"                                
{
  rtx last;

  operands[3] = gen_reg_rtx (Pmode);
...

In other words, we declare an array with size 3: "rtx operands[3]", and then write the 4th element: "operands[3] = gen_reg_rtx (Pmode)".
Comment 2 Tom de Vries 2017-11-22 16:54:07 UTC
This looks like the offending commit:
...
commit 0e3876bfd55e2888a012d3e304196eb2d4231ecf
Author: olegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue May 3 06:47:34 2016 +0000

    gcc/
        * config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
        (mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
        define_insn_and_split.
        (mulsi3_i): New define_insn_and_split.
        (mulsi3_call): Convert to define_insn.
        (mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
        Remove constraints.
...

which contains this change:
...
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index da1dfe9..2d9502b 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -2244,16 +2244,9 @@
 
 
 (define_expand "udivsi3"
-  [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
-   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
-   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
-   (parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (udiv:SI (reg:SI R4_REG)
-                           (reg:SI R5_REG)))
-             (clobber (reg:SI T_REG))
-             (clobber (reg:SI PR_REG))
-             (clobber (reg:SI R4_REG))
-             (use (match_dup 3))])]
+  [(set (match_operand:SI 0 "register_operand")
+       (udiv:SI (match_operand:SI 1 "general_operand")
+                (match_operand:SI 2 "general_operand")))]
   ""
 {
   rtx last;
...

The "operands[3]" refers to the "(match_dup 3)" that was removed here.
Comment 3 Tom de Vries 2017-11-22 17:31:37 UTC
By reverting the patch, I was able to finish the build.
Comment 4 Oleg Endo 2017-11-23 04:28:04 UTC
Thanks for reporting and tracking this down.
It seems there more such traps.  Can you please try the following:

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 251045)
+++ gcc/config/sh/sh.md	(working copy)
@@ -2277,8 +2277,8 @@
   ""
 {
   rtx last;
+  rtx func_ptr = gen_reg_rtx (Pmode);
 
-  operands[3] = gen_reg_rtx (Pmode);
   /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_DIVIDE_CALL_TABLE)
     {
@@ -2298,16 +2298,16 @@
 	  emit_move_insn (operands[0], operands[2]);
 	  DONE;
 	}
-      function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
-      last = gen_udivsi3_i4_int (operands[0], operands[3]);
+      function_symbol (func_ptr, "__udivsi3_i4i", SFUNC_GOT);
+      last = gen_udivsi3_i4_int (operands[0], func_ptr);
     }
   else if (TARGET_DIVIDE_CALL_FP)
     {
-      rtx lab = function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC).lab;
+      rtx lab = function_symbol (func_ptr, "__udivsi3_i4", SFUNC_STATIC).lab;
       if (TARGET_FPU_SINGLE)
-	last = gen_udivsi3_i4_single (operands[0], operands[3], lab);
+	last = gen_udivsi3_i4_single (operands[0], func_ptr, lab);
       else
-	last = gen_udivsi3_i4 (operands[0], operands[3], lab);
+	last = gen_udivsi3_i4 (operands[0], func_ptr, lab);
     }
   else if (TARGET_SH2A)
     {
@@ -2318,8 +2318,8 @@
     }
   else
     {
-      rtx lab = function_symbol (operands[3], "__udivsi3", SFUNC_STATIC).lab;
-      last = gen_udivsi3_i1 (operands[0], operands[3], lab);
+      rtx lab = function_symbol (func_ptr, "__udivsi3", SFUNC_STATIC).lab;
+      last = gen_udivsi3_i1 (operands[0], func_ptr, lab);
     }
   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
@@ -2405,22 +2405,22 @@
   ""
 {
   rtx last;
+  rtx func_ptr = gen_reg_rtx (Pmode);
 
-  operands[3] = gen_reg_rtx (Pmode);
   /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_DIVIDE_CALL_TABLE)
     {
-      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
-      last = gen_divsi3_i4_int (operands[0], operands[3]);
+      function_symbol (func_ptr, sh_divsi3_libfunc, SFUNC_GOT);
+      last = gen_divsi3_i4_int (operands[0], func_ptr);
     }
   else if (TARGET_DIVIDE_CALL_FP)
     {
-      rtx lab = function_symbol (operands[3], sh_divsi3_libfunc,
+      rtx lab = function_symbol (func_ptr, sh_divsi3_libfunc,
 				 SFUNC_STATIC).lab;
       if (TARGET_FPU_SINGLE)
-	last = gen_divsi3_i4_single (operands[0], operands[3], lab);
+	last = gen_divsi3_i4_single (operands[0], func_ptr, lab);
       else
-	last = gen_divsi3_i4 (operands[0], operands[3], lab);
+	last = gen_divsi3_i4 (operands[0], func_ptr, lab);
     }
   else if (TARGET_SH2A)
     {
@@ -2431,8 +2431,8 @@
     }
   else
     {
-      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
-      last = gen_divsi3_i1 (operands[0], operands[3]);
+      function_symbol (func_ptr, sh_divsi3_libfunc, SFUNC_GOT);
+      last = gen_divsi3_i1 (operands[0], func_ptr);
     }
   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
@@ -6519,6 +6519,7 @@
   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
 	 (match_operand 1 "" ""))
    (use (reg:SI FPSCR_MODES_REG))
+   (use (match_scratch 2))
    (clobber (reg:SI PR_REG))]
   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
 {
@@ -6629,6 +6630,7 @@
 	(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
 	      (match_operand 2 "" "")))
    (use (reg:SI FPSCR_MODES_REG))
+   (use (match_scratch 3))
    (clobber (reg:SI PR_REG))]
   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
 {
@@ -7044,13 +7046,11 @@
   [(const_int 0)]
 {
   rtx lab = PATTERN (gen_call_site ());
-  rtx call_insn;
+  rtx tmp =  gen_rtx_REG (SImode, R1_REG);
 
-  operands[3] =  gen_rtx_REG (SImode, R1_REG);
-
-  sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
-  call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
-							operands[3],
+  sh_expand_sym_label2reg (tmp, operands[1], lab, true);
+  rtx call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
+							tmp,
 							operands[2],
 							copy_rtx (lab)));
   SIBLING_CALL_P (call_insn) = 1;
@@ -7078,12 +7078,11 @@
   [(const_int 0)]
 {
   rtx lab = PATTERN (gen_call_site ());
+  rtx tmp = gen_rtx_REG (SImode, R1_REG);
 
-  operands[3] =  gen_rtx_REG (SImode, R1_REG);
-
-  sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
+  sh_expand_sym_label2reg (tmp, operands[1], lab, true);
   rtx i = emit_call_insn (gen_sibcall_valuei_pcrel_fdpic (operands[0],
-							  operands[3],
+							  tmp,
 							  operands[2],
 							  copy_rtx (lab)));
   SIBLING_CALL_P (i) = 1;
Comment 5 Tom de Vries 2017-11-23 10:09:05 UTC
(In reply to Oleg Endo from comment #4)
> Thanks for reporting and tracking this down.
> It seems there more such traps.  Can you please try the following:

I've done an sh-elf build using this patch, and that went ok.

FWIW, I've also done an sh-unknown-linux-gnu build and that gets as far as it can get without an sh runtime installation.

I don't have a complete sh build and test setup. Somebody needs to build and test this patch for the sh target.
Comment 6 Oleg Endo 2017-11-23 14:06:47 UTC
Author: olegendo
Date: Thu Nov 23 14:06:15 2017
New Revision: 255096

URL: https://gcc.gnu.org/viewcvs?rev=255096&root=gcc&view=rev
Log:
gcc/
	PR target/83111
	* config/sh/sh.md (udivsi3, divsi3, sibcall_value_pcrel,
	sibcall_value_pcrel_fdpic): Use local variable instead of
	operands[3].
	(calli_tbr_rel): Add missing operand 2.
	(call_valuei_tbr_rel): Add missing operand 3.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sh/sh.md
Comment 7 Oleg Endo 2017-11-23 14:08:43 UTC
Author: olegendo
Date: Thu Nov 23 14:08:12 2017
New Revision: 255097

URL: https://gcc.gnu.org/viewcvs?rev=255097&root=gcc&view=rev
Log:
gcc/
	Backport from mainline
	2017-11-23  Oleg Endo  <olegendo@gcc.gnu.org>

	PR target/83111
	* config/sh/sh.md (udivsi3, divsi3, sibcall_value_pcrel,
	sibcall_value_pcrel_fdpic): Use local variable instead of
	operands[3].
	(calli_tbr_rel): Add missing operand 2.
	(call_valuei_tbr_rel): Add missing operand 3.


Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/config/sh/sh.md
Comment 8 Oleg Endo 2017-11-23 14:11:46 UTC
Fixed on GCC 7 and GCC 8.