This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
SUBREG vs. flow.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: SUBREG vs. flow.c
- From: Jim Kingdon <kingdon at redhat dot com>
- Date: Thu, 23 Sep 1999 11:21:07 -0400
- CC: davem at redhat dot com
Consider the case in which there is a SET to an HI mode register
followed by a SET to a SUBREG of that register in QI mode (e.g. %ax
and %al on x86). The flow.c pass will get confused about whether the
first SET can be optimized out.
The following patch fixes it. If there is a better way let me know.
1999-09-23 Jim Kingdon <http://developer.redhat.com>
* flow.c (mark_used_regs): Use REG_BYTES rather than REG_SIZE.
--- egcs-1.1.2/gcc/flow.c~ Wed Sep 8 14:34:36 1999
+++ egcs-1.1.2/gcc/flow.c Thu Sep 23 10:21:26 1999
@@ -2763,7 +2763,7 @@
does not use any of the old value. But these other
ways of storing in a register do use the old value. */
if (GET_CODE (testreg) == SUBREG
- && !(REG_SIZE (SUBREG_REG (testreg)) > REG_SIZE (testreg)))
+ && !(REG_BYTES (SUBREG_REG (testreg)) > REG_BYTES (testreg)))
;
else
mark_dest = 1;
------------------------------ excerpt from .cse2 dump:
(insn 33 6 36 (set (reg:HI 28)
(const_int 0)) 58 {movhi+1} (nil)
(nil))
(insn 36 33 11 (set (subreg:QI (reg:HI 28) 0)
(const_int 65)) 64 {movqi+1} (nil)
(nil))
------------------------------ test case (EGCS 1.1.2):
[kingdon@porky sap]$ cat bug.c
#include <stdio.h>
#include <stdlib.h>
/*#define TRAILER 0x07*/
#define TRAILER 'A'
static char buf[40];
static char line[30] = "1234567890123456789012345678*";
static void f()
{
char trailer[2] = { TRAILER, 0x00 };
char* const last = buf + sizeof(line) - 2;
memcpy(buf, line, sizeof(line));
if (*last == '*')
{
memcpy(last, trailer, 2);
}
}
int main()
{
f();
printf("%s\n", buf);
return 0;
}
[kingdon@porky sap]$ gcc -g -O bug.c
[kingdon@porky sap]$ ./a.out
1234567890123456789012345678A] <----- note extra "]"
[kingdon@porky sap]$