This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] h8300: Fix target/11805.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 21 Aug 2003 09:09:35 -0400 (EDT)
- Subject: [patch] h8300: Fix target/11805.
Hi,
Attached is a patch to fix target/11805 on h8300 port.
Consider the following piece of code.
unsigned char
foo (unsigned char a)
{
return (a & 1) > 0;
}
If this is compiled with h8300-hms-gcc -mh -O2, the fianl rtx contains
the following sequence.
(set (cc0)
(and:HI (reg:HI 0)
(const_int 1)))
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(label_ref 17)
(pc)))
On h8300, the first insn does not set the overflow flag, but the
second requires the overflow flag. As a result, when the final wants
to output the jump insn, it cannot find a test insn that gives
appropriate condition flags.
The patch fixes the problem by simply deleting a pattern that matches
the first insn above. With the patch, the above sequence is
represented as
(set (reg:HI 20)
(and:HI (subreg:HI (reg/v:QI 17) 0)
(const_int 1)))
(set (cc0)
(reg:HI 20))
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(label_ref 17)
(pc)))
Another reason for deleting the pattern is that it is not cannonical.
The canonical form of a single bit extraction would be
(set (cc0)
(zero_extract ...)).
The same applies for the bit test instruction in SImode.
Tested on h8300 port. Committed to 3.3 branch and mainline.
Kazu Hirata
2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
PR target/11805
* config/h8300/h8300.md (two anonymous patterns): Remove.
2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
PR target/11805
* gcc.c-torture/compile/20030821-1.c: New.
Index: h8300.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.md,v
retrieving revision 1.233
diff -u -r1.233 h8300.md
--- h8300.md 10 Jul 2003 06:18:30 -0000 1.233
+++ h8300.md 21 Aug 2003 02:21:15 -0000
@@ -652,43 +652,6 @@
(match_dup 3)))]
"operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
-(define_insn ""
- [(set (cc0)
- (and:HI (match_operand:HI 0 "register_operand" "r")
- (match_operand:HI 1 "single_one_operand" "n")))]
- ""
- "*
-{
- operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
- if (INTVAL (operands[1]) > 128)
- {
- operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
- return \"btst\\t%V1,%t0\";
- }
- return \"btst\\t%V1,%s0\";
-}"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
-(define_insn ""
- [(set (cc0)
- (and:SI (match_operand:SI 0 "register_operand" "r")
- (match_operand:SI 1 "single_one_operand" "n")))]
- "(TARGET_H8300H || TARGET_H8300S)
- && (INTVAL (operands[1]) & 0xffff) != 0"
- "*
-{
- operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
- if (INTVAL (operands[1]) > 128)
- {
- operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
- return \"btst\\t%V1,%x0\";
- }
- return \"btst\\t%V1,%w0\";
-}"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
(define_insn "tstqi"
[(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
""
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ 20030821-1.c 2003-08-21 00:17:24.000000000 -0400
@@ -0,0 +1,24 @@
+/* PR target/11805. */
+
+/* Consider the following sequence.
+
+ (set (cc0)
+ (and:HI (reg:HI 0)
+ (const_int 1)))
+
+ (set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref 17)
+ (pc)))
+
+ On h8300, the first insn does not set the overflow flag, but the
+ second requires the overflow flag. As a result, when the final
+ wants to output the jump insn, it cannot find a test insn that
+ gives appropriate condition flags. */
+
+unsigned char
+foo (unsigned char a)
+{
+ return (a & 1) > 0;
+}