Bug 40153 - Long long comparison optimized away incorrectly in Thumb code.
Summary: Long long comparison optimized away incorrectly in Thumb code.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.3.4
Assignee: Richard Earnshaw
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-05-14 22:00 UTC by Doug Kwan
Modified: 2009-05-16 23:06 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: arm-unknown-linux-gnueabi
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail: 4.5.0 4.4.0 4.3.1 4.3.3
Last reconfirmed: 2009-05-16 13:49:20


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Doug Kwan 2009-05-14 22:00:26 UTC
Several versions of gcc (trunk, 4.4.0, 4.3.1 and 4.3.3) mis-compiled this test case.

----bug.c----
/* compile with -Os -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;
}
------

sh-3.2$ arm-unknown-linux-gnueabi-gcc -Os -mthumb bug.c
sh-3.2$ /disk2/dougkwan/qemu/install/bin/qemu-arm -L ~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/sys-root a.out
qemu: uncaught target signal 6 (Aborted) - exiting
sh-3.2$ arm-unknown-linux-gnueabi-gcc  -mthumb bug.csh-3.2$ /disk2/dougkwan/qemu/install/bin/qemu-arm -L ~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/sys-root a.out
sh-3.2$ 

Below is code generate for the function cmp:
----
        .align  1
        .global cmp
        .code   16
        .thumb_func
        .type   cmp, %function
cmp:
        push    {lr}
        ldr     r3, [r0]
        ldr     r2, [r1]
        ldr     r3, [r3]
        ldr     r2, [r2]
        cmp     r2, r3
        bhi     .L6
        mov     r0, #0
        b       .L2
.L6:
        mov     r0, #1
        neg     r0, r0
.L2:
        @ sp needed for prologue
        pop     {pc}
        .size   cmp, .-cmp
        .align  1

Note that the compiled function only returns 0 and 1 where as the same function in the source code return values -1, 0 and 1.
Comment 1 Doug Kwan 2009-05-15 07:08:52 UTC
This is caused by a typo in arm.md.

(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")]
)

The instruction cstoresi_nltu_thumb1 is used to compute the expression -(x < y) where x and y are unsigned SI-type values.  The operand of the NEG RTX should be a LTU RTX instead of a GTU RTX.  The incorrected RTX code caused a later CSE pass to substitute this pattern:

(set x
    (neg (gtu a b)))   <=== cstoresi_nltu_thumb1
(set y (neg x))        

with

(set y (gtu a b))

I tried fixing the RTX code and the test case passed.
Comment 2 Ramana Radhakrishnan 2009-05-15 08:26:08 UTC
(In reply to comment #1)
> This is caused by a typo in arm.md.
> 
> (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")]
> )
> 
> The instruction cstoresi_nltu_thumb1 is used to compute the expression -(x < y)
> where x and y are unsigned SI-type values.  The operand of the NEG RTX should
> be a LTU RTX instead of a GTU RTX.  The incorrected RTX code caused a later CSE
> pass to substitute this pattern:
> 
> (set x
>     (neg (gtu a b)))   <=== cstoresi_nltu_thumb1
> (set y (neg x))        
> 
> with
> 
> (set y (gtu a b))
> 
> I tried fixing the RTX code and the test case passed.
> 

This looks correct. Please submit a patch to gcc-patches@.
Comment 3 Doug Kwan 2009-05-15 08:28:52 UTC
Subject: Re:  Long long comparison optimized away 
	incorrectly in Thumb code.

I am running regression tests and will submit a patch tomorrow morning
after that.

-Doug

2009/5/15 ramana at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org>:
>
>
> ------- Comment #2 from ramana at gcc dot gnu dot org  2009-05-15 08:26 -------
> (In reply to comment #1)
>> This is caused by a typo in arm.md.
>>
>> (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")]
>> )
>>
>> The instruction cstoresi_nltu_thumb1 is used to compute the expression -(x < y)
>> where x and y are unsigned SI-type values.  The operand of the NEG RTX should
>> be a LTU RTX instead of a GTU RTX.  The incorrected RTX code caused a later CSE
>> pass to substitute this pattern:
>>
>> (set x
>>     (neg (gtu a b)))   <=== cstoresi_nltu_thumb1
>> (set y (neg x))
>>
>> with
>>
>> (set y (gtu a b))
>>
>> I tried fixing the RTX code and the test case passed.
>>
>
> This looks correct. Please submit a patch to gcc-patches@.
>
>
> --
>
> ramana at gcc dot gnu dot org changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>             Status|UNCONFIRMED                 |NEW
>     Ever Confirmed|0                           |1
>   Last reconfirmed|0000-00-00 00:00:00         |2009-05-15 08:26:09
>               date|                            |
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40153
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
>
Comment 4 Richard Earnshaw 2009-05-16 12:53:41 UTC
Subject: Bug 40153

Author: rearnsha
Date: Sat May 16 12:53:22 2009
New Revision: 147613

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147613
Log:
	PR target/40153
	* arm.md (cstoresi_nltu_thumb1): Use a neg of ltu as the pattern name
	implies.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm.md

Comment 5 Richard Earnshaw 2009-05-16 13:28:41 UTC
Subject: Bug 40153

Author: rearnsha
Date: Sat May 16 13:28:27 2009
New Revision: 147614

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147614
Log:
	PR target/40153
	* arm.md (cstoresi_nltu_thumb1): Use a neg of ltu as the pattern name
	implies.

Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/config/arm/arm.md

Comment 6 Doug Kwan 2009-05-16 17:46:49 UTC
Thanks for fixing this.  I also submitted a patch yesterday with the same fix and a test case also.  The bug is fixed but I think we still want the test case, right?

(In reply to comment #4)
> Subject: Bug 40153
> 
> Author: rearnsha
> Date: Sat May 16 12:53:22 2009
> New Revision: 147613
> 
> URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147613
> Log:
>         PR target/40153
>         * arm.md (cstoresi_nltu_thumb1): Use a neg of ltu as the pattern name
>         implies.
> 
> Modified:
>     trunk/gcc/ChangeLog
>     trunk/gcc/config/arm/arm.md
> 

Comment 7 Richard Earnshaw 2009-05-16 23:04:24 UTC
Subject: Bug 40153

Author: rearnsha
Date: Sat May 16 23:04:06 2009
New Revision: 147626

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147626
Log:
	PR target/40153
	* arm.md (cstoresi_nltu_thumb1): Use a neg of ltu as the pattern name
	implies.

Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/config/arm/arm.md

Comment 8 Richard Earnshaw 2009-05-16 23:06:41 UTC
(In reply to comment #6)
> Thanks for fixing this.  I also submitted a patch yesterday with the same fix
> and a test case also.  The bug is fixed but I think we still want the test
> case, right?

Sorry, didn't see your patch.  I don't think another test is really necessary, this fixes so many failures on trunk that I don't see the need for an additional test.