This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]