Bug 36447 - [4.4 Regression] simplify_subreg ICE with right shift more than length type AVR
Summary: [4.4 Regression] simplify_subreg ICE with right shift more than length type AVR
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-06-06 02:38 UTC by Andy Hutchinson
Modified: 2008-06-10 15:43 UTC (History)
2 users (show)

See Also:
Host: i686-pc-cygwin
Target: avr-unknown-none
Build: i686-pc-cygwin
Known to work: 4.2.2
Known to fail: 4.4.0
Last reconfirmed: 2008-06-06 05:04:36


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andy Hutchinson 2008-06-06 02:38:55 UTC
Works on avr-gcc (GCC) 4.2.2 (WinAVR 20071221). Does not on 4.4 HEAD.

Test results posts show this test failing since AT LEAST SVN rev 132993 on AVR (March 3 2008)  (before that test was not run - so dont know when it started. 


gcc-c/toture/unsorted/shm.c

foo (int *p)
{
  int a = *p;
  return a >> 24;
}

/home/hutchia/Desktop/gcc/gcc/testsuite/gcc.c-torture/unsorted/shm.c:5: internal compiler error: in simplify_subreg, at simplify-rtx.c:4962

test.c: In function 'foo':
test.c:4: warning: right shift count >= width of type

Analyzing compilation unit
Performing interprocedural optimizations
 <visibility> <early_local_cleanups> <summary generate> <inline> <static-var> <p
ure-const>Assembling functions:
 foo
Breakpoint 1, fancy_abort (file=0xb030f2 "../../gcc/gcc/simplify-rtx.c",
    line=4962, function=0xb03158 "simplify_subreg")
    at ../../gcc/gcc/diagnostic.c:654
654       internal_error ("in %s, at %s:%d", function, trim_filename (file), lin
e);
(gdb) where
#0  fancy_abort (file=0xb030f2 "../../gcc/gcc/simplify-rtx.c", line=4962,
    function=0xb03158 "simplify_subreg") at ../../gcc/gcc/diagnostic.c:654
#1  0x007a1143 in simplify_subreg (outermode=QImode, op=0x7ff24f20,
    innermode=HImode, byte=3) at ../../gcc/gcc/simplify-rtx.c:4937
#2  0x007a1672 in simplify_gen_subreg (outermode=QImode, op=0x7ff24f20,
    innermode=HImode, byte=3) at ../../gcc/gcc/simplify-rtx.c:5287
#3  0x007a0b83 in simplify_subreg (outermode=QImode, op=0x7ff25100,
    innermode=HImode, byte=0) at ../../gcc/gcc/simplify-rtx.c:5271
#4  0x007a1672 in simplify_gen_subreg (outermode=QImode, op=0x7ff25100,
    innermode=HImode, byte=0) at ../../gcc/gcc/simplify-rtx.c:5287
#5  0x0098f86a in propagate_rtx_1 (px=0x22caf4, old=0x4, new=0x7ff25100,
    flags=2) at ../../gcc/gcc/fwprop.c:333
#6  0x009907da in forward_propagate_into (use=0x0)
    at ../../gcc/gcc/fwprop.c:457
#7  0x00990bc2 in fwprop () at ../../gcc/gcc/fwprop.c:1055
#8  0x00624a0e in execute_one_pass (pass=0x0) at ../../gcc/gcc/passes.c:1292
#9  0x00624b33 in execute_pass_list (pass=0xa8c320)
    at ../../gcc/gcc/passes.c:1342
#10 0x00624b46 in execute_pass_list (pass=0xa8c5c0)
    at ../../gcc/gcc/passes.c:1343
#11 0x0084d899 in tree_rest_of_compilation (fndecl=0x7fdbf1f0)
    at ../../gcc/gcc/tree-optimize.c:421
#12 0x00625d4b in cgraph_expand_function (node=0x7ff40280)
    at ../../gcc/gcc/cgraphunit.c:1148
#13 0x0062793e in cgraph_optimize () at ../../gcc/gcc/cgraphunit.c:1211
#14 0x0041bee7 in c_write_global_declarations ()
    at ../../gcc/gcc/c-decl.c:8062
#15 0x0062c95b in toplev_main (argc=3, argv=0x1c014c0)
    at ../../gcc/gcc/toplev.c:976
#16 0x0049467a in main (argc=3, argv=0x1c014c0) at ../../gcc/gcc/main.c:35
Comment 1 Andy Hutchinson 2008-06-06 03:08:44 UTC
rev 132971 appears to have created this  problem.

Revision: 132971
Author: bonzini
Date: 8:30:10 AM, Thursday, March 06, 2008
Message:
2008-03-06  Paolo Bonzini  <bonzini@gnu.org>

	* simplify-rtx.c (simplify_subreg): Remove useless shifts from
	word-extractions out of a multi-word object.

----
Modified : /trunk/gcc/ChangeLog
Modified : /trunk/gcc/simplify-rtx.c


It fails because subreg simplification tries to extract byte 3 of the HImode int 'a' at simplify-rtx 5271. No check is performed here to see if shift count >= length. For this case simplification should give sign of value (-1 or 0).

Comment 2 Paolo Bonzini 2008-06-06 05:04:36 UTC
Can you try and possibly submit this patch:

Index: /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c
===================================================================
--- /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c  (revision 134435)
+++ /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c  (working copy)
@@ -5247,6 +5247,7 @@ simplify_subreg (enum machine_mode outer
       && GET_MODE_BITSIZE (innermode) >= (2 * GET_MODE_BITSIZE (outermode))
       && GET_CODE (XEXP (op, 1)) == CONST_INT
       && (INTVAL (XEXP (op, 1)) & (GET_MODE_BITSIZE (outermode) - 1)) == 0
+      && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)
       && byte == subreg_lowpart_offset (outermode, innermode))
     {
       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;

Thanks!
Comment 3 Andy Hutchinson 2008-06-06 11:55:57 UTC
Subject: Re:  simplify_subreg ICE with right shift more than
 length type AVR

Thanks for quick response,

I will give this a try and no doubt it will work.
I was trying to think of how the other case should be simplified, 
rather than left as shift.

or put another way, how should we take sign?


Andy



----------------------------------------------
Sent from my Dingleberry wired device.


-----Original Message-----
From: bonzini at gnu dot org <gcc-bugzilla@gcc.gnu.org>
To: hutchinsonandy@aim.com
Sent: Fri, 6 Jun 2008 1:04 am
Subject: [Bug middle-end/36447] simplify_subreg ICE with right shift 
more than length type AVR




------- Comment #2 from bonzini at gnu dot org  2008-06-06 05:04 -------
Can you try and possibly submit this patch:

Index: /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c
===================================================================
--- /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c  (revision 134435)
+++ /Users/bonzinip/cvs/gcc/gcc/simplify-rtx.c  (working copy)
@@ -5247,6 +5247,7 @@ simplify_subreg (enum machine_mode outer
        && GET_MODE_BITSIZE (innermode) >= (2 * GET_MODE_BITSIZE 
(outermode))
       && GET_CODE (XEXP (op, 1)) == CONST_INT
        && (INTVAL (XEXP (op, 1)) & (GET_MODE_BITSIZE (outermode) - 1)) 
== 0
+      && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)
       && byte == subreg_lowpart_offset (outermode, innermode))
     {
       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;

Thanks!


--

bonzini at gnu dot org changed:

           What    |Removed                     |Added
-------------------------------------------------------------------------
---
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|0                           |1
   Last reconfirmed|0000-00-00 00:00:00         |2008-06-06 05:04:36
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36447

------- You are receiving this mail because: -------
You reported the bug, or are watching the reporter.

Comment 4 Andy Hutchinson 2008-06-09 22:39:21 UTC
Subject: Bug 36447

Author: hutchinsonandy
Date: Mon Jun  9 22:38:34 2008
New Revision: 136602

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136602
Log:
PR middle-end/36447
* simplify-rtx.c (simplify_subreg): Add check for shift count greater than size.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/simplify-rtx.c

Comment 5 Eric Weddington 2008-06-10 15:43:18 UTC
Fixed for 4.4.0.