This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix PR39715 part 2
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Earnshaw <rearnsha at arm dot com>
- Date: Sat, 1 Aug 2009 23:24:19 +0200
- Subject: [PATCH] fix PR39715 part 2
This patch fixes another useless sign extension on ARM. Actually I
am not sure this is a regression.
The cause here is the expansion of (A < B) as
(set (reg:SI A) (neg:SI (lt:SI (reg:SI B) (reg:SI C))))
(set (reg:SI D) (neg:SI (reg:SI A)))
In combine, GCC loses track of the nonzero_bits of pseudo D because
of this:
#if 0
/* Disabled to avoid exponential mutual recursion between nonzero_bits
and num_sign_bit_copies. */
if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (x))
== GET_MODE_BITSIZE (GET_MODE (x)))
nonzero = 1;
#endif
To work around it, I changed the (A < B) pattern so that it is split
after combine.
Tested i686-pc-linux-gnu, plus on arm-elf I looked by hand at some
testcases to test the paths I modified, but building a combined
tree failed with an internal assembler error.
Ok?
Paolo
2009-08-01 Paolo Bonzini <bonzini@gnu.org>
* config/arm/arm.md (cstoresi4): Use cstoresi_ltu_thumb1.
(cstoresi_ltu_thumb1): New define_insn_and_split.
2009-08-01 Paolo Bonzini <bonzini@gnu.org>
* gcc.target/arm/thumb-ltu.c: New.
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md (branch cond-optab2)
+++ gcc/config/arm/arm.md (working copy)
@@ -8067,15 +8067,13 @@
if (!thumb1_cmp_operand (op3, SImode))
op3 = force_reg (SImode, op3);
scratch = gen_reg_rtx (SImode);
- emit_insn (gen_cstoresi_nltu_thumb1 (scratch, operands[2], op3));
- emit_insn (gen_negsi2 (operands[0], scratch));
+ emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
break;
case GTU:
op3 = force_reg (SImode, operands[3]);
scratch = gen_reg_rtx (SImode);
- emit_insn (gen_cstoresi_nltu_thumb1 (scratch, op3, operands[2]));
- emit_insn (gen_negsi2 (operands[0], scratch));
+ emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
break;
/* No good sequences for GT, LT. */
@@ -8168,6 +8167,20 @@
[(set_attr "length" "4")]
)
+(define_insn_and_split "cstoresi_ltu_thumb1"
+ [(set (match_operand:SI 0 "s_register_operand" "=l,l")
+ (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
+ (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
+ "TARGET_THUMB1 && !(reload_in_progress || reload_completed)"
+ "#"
+ "TARGET_THUMB1 && !(reload_in_progress || reload_completed)"
+ [(set (match_dup 3)
+ (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
+ (set (match_dup 0) (neg:SI (match_dup 3)))]
+ "operands[3] = gen_reg_rtx (SImode);"
+ [(set_attr "length" "4")]
+)
+
;; Used as part of the expansion of thumb les sequence.
(define_insn "thumb1_addsi3_addgeu"
[(set (match_operand:SI 0 "s_register_operand" "=l")
/* { dg-do compile } */
/* { dg-options "-mcpu=arm1136jf-s -mthumb -O2" } */
void f(unsigned a, unsigned b, unsigned c, unsigned d)
{
if (a <= b || c > d)
foo();
else
bar();
}
/* { dg-final { scan-assembler-not "uxtb" } } */