[PATCH][ARM] Fix a bug in cstoresi_nltu_thumb1 that causes CSE to produce incorrect code
Doug Kwan (關振德)
dougkwan@google.com
Sat May 16 00:14:00 GMT 2009
Sorry, forgot that patch :)
2009-05-15 Doug Kwan <dougkwan@google.com>
testsuite/ChangeLog
* gcc.target/arm/40153.c: New test.
ChangeLog
PR target/40153
* config/arm/arm.md (cstoresi_nltu_thumb1): Fix typo that caused CSE
to produce incorrect code.
2009/5/15 Doug Kwan (關振德) <dougkwan@google.com>:
> Hi
>
> This patch fixes a typo in the RTL instruction
> cstoresi_nltu_thumb1 that causes bad THUMB code to be generated in the
> arm-eabi target. The instruction is meant to compute the expression
> -(x < y) where x and y of unsigned SI type. The current RTL looks
> like this in trunk, gcc-4.4 and gcc-4.3:
>
> (define_insn "cstoresi_nltu_thumb1"
> [(set (match_operand:SI 0 "s_register_operand" "=l,l")
> (neg:SI (gtu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
> (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
> "TARGET_THUMB1"
> "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
> [(set_attr "length" "4")]
> )
>
> It is quite obvious that source operand of the NEG RTX should be an
> LTU RTX instead of a GTU RTX. The incorrectly use of GTU sometims
> causes CSE to generate bad code if there is another GTU RTX with the
> same operands before the the cstoresi_nltu_thumb1 instruction.
> Details are in the gcc bugzilla page.
>
> I have tested fix in this patch using the test case also in the patch.
> I will check this in after approval and regression testing.
>
> -Doug
>
-------------- next part --------------
Index: gcc/testsuite/gcc.target/arm/40153.c
===================================================================
--- gcc/testsuite/gcc.target/arm/40153.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/40153.c (revision 0)
@@ -0,0 +1,54 @@
+/* { dg-options "-O2 -mthumb" } */
+
+extern void abort (void);
+static int llcmp (long long a, long long b);
+
+struct info
+{
+ long unsigned ll;
+};
+
+int __attribute__((noinline))
+cmp (const void *a, const void *b)
+{
+ struct info *pa = *((struct info **) a);
+ struct info *pb = *((struct info **) b);
+ return llcmp (pa->ll, pb->ll);
+}
+
+static int
+llcmp (long long a, long long b)
+{
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+}
+
+int
+main ()
+{
+ struct info pa, pb;
+ struct info *unsorted[2];
+
+ unsorted[0] = &pa;
+ unsorted[1] = &pb;
+
+ pa.ll = 1;
+ pb.ll = 2;
+ if (cmp (&unsorted[0], &unsorted[1]) != -1)
+ abort ();
+
+ pa.ll = 2;
+ pb.ll = 1;
+ if (cmp (&unsorted[0], &unsorted[1]) != 1)
+ abort ();
+
+ pa.ll = 1;
+ pb.ll = 1;
+ if (cmp (&unsorted[0], &unsorted[1]) != 0)
+ abort ();
+
+ return 0;
+}
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md (revision 147551)
+++ gcc/config/arm/arm.md (working copy)
@@ -7977,7 +7977,7 @@
(define_insn "cstoresi_nltu_thumb1"
[(set (match_operand:SI 0 "s_register_operand" "=l,l")
- (neg:SI (gtu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
+ (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
(match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
"TARGET_THUMB1"
"cmp\\t%1, %2\;sbc\\t%0, %0, %0"
More information about the Gcc-patches
mailing list