public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch, ARM] ICE in get_arm_condition_code()
@ 2011-01-13  1:37 Chung-Lin Tang
  2011-01-13 11:33 ` Ramana Radhakrishnan
  2011-01-26  3:48 ` Chung-Lin Tang
  0 siblings, 2 replies; 5+ messages in thread
From: Chung-Lin Tang @ 2011-01-13  1:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: paul, rearnsha

[-- Attachment #1: Type: text/plain, Size: 2266 bytes --]

Hi,
there's an ICE in arm.c:get_arm_condition_code(), from here:
https://bugs.launchpad.net/gcc-linaro/+bug/689887

The report was on a 4.5 based compiler, but I verified it also occurs on
current trunk, under Thumb-2.

The problem as I found, happens in RTL ifcvt after the combine pass.
ifcvt.c:noce_emit_cmove() creates this:
(insn 58 57 59 4 (parallel [
            (set (reg:CC_NCV 24 cc)
                (compare:CC_NCV (reg:DI 140)
                    (reg:DI 147)))
            (clobber (scratch:SI))
        ]) p.c:13 202 {*arm_cmpdi_insn}
     (nil))

(insn 59 58 60 4 (set (reg:SI 146)
	(if_then_else:SI (gt (reg:CC_NCV 24 cc)
                (const_int 0 [0]))
            (reg:SI 145)
            (reg:SI 144))) p.c:13 701 {*thumb2_movsicc_insn}
     (nil))

which is wrong; the GT comparison requires testing of the Z, C, and V
flags, which CC_NCV does not satisfy. The ICE happens later when the asm
emitting actually hits assert fail in get_arm_condition_code().

This patch fixes this by stratifying the "arm_comparison_operator"
predicate, by leveraging the current logic in get_arm_condition_code().
I abstracted out the body into a new arm_comparison_to_cond_code()
function, which returns an invalid code instead of assert fail, and used
it to add a check to the comparison RTX in "arm_comparison_operator".
This way, invalid comparisons like the above would be blocked from emitting.

Tests were run with no regressions found. Okay for trunk?

Thanks,
Chung-Lin

2011-01-12  Chung-Lin Tang  <cltang@codesourcery.com>

        * config/arm/arm.h (enum arm_cond_code): Add ARM_COND_INVALID.
        * config/arm/arm.c (arm_comparison_to_cond_code): Renamed from
        get_arm_condition_code(), change gcc_unreachable()s to return
        ARM_COND_INVALID.
        (get_arm_condition_code): Implement by calling
        arm_comparison_to_cond_code(), with result test by gcc_assert().
        (arm_valid_comparison_p): New function to test for valid ARM
        comparison RTX.
        * config/arm/arm-protos.h (arm_valid_comparison_p): Add
	prototype.
        * config/arm/predicates.md (arm_comparison_operator): Add
	additional check based on arm_valid_comparison_p().

        testsuite/
        * gcc.target/arm/20110112-1.c: New test.




[-- Attachment #2: arm-cmp.diff --]
[-- Type: text/x-patch, Size: 5623 bytes --]

Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 168663)
+++ config/arm/arm.c	(working copy)
@@ -90,6 +90,7 @@
 static bool arm_print_operand_punct_valid_p (unsigned char code);
 static const char *fp_const_from_val (REAL_VALUE_TYPE *);
 static arm_cc get_arm_condition_code (rtx);
+static arm_cc arm_comparison_to_cond_code (rtx);
 static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
 static rtx is_jump_table (rtx);
 static const char *output_multi_immediate (rtx *, const char *, const char *,
@@ -16942,6 +16943,23 @@
 static enum arm_cond_code
 get_arm_condition_code (rtx comparison)
 {
+  enum arm_cond_code code = arm_comparison_to_cond_code (comparison);
+  gcc_assert (code != ARM_COND_INVALID);
+  return code;
+}
+
+/* Tests if the comparison RTX is valid for ARM. */
+bool
+arm_valid_comparison_p (rtx comparison)
+{
+  return (arm_comparison_to_cond_code (comparison) != ARM_COND_INVALID);
+}
+
+/* Function that maps the relation between comparison RTX
+   vs. ARM condition codes, */
+static enum arm_cond_code
+arm_comparison_to_cond_code (rtx comparison)
+{
   enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
   enum arm_cond_code code;
   enum rtx_code comp_code = GET_CODE (comparison);
@@ -16977,7 +16995,7 @@
 	case EQ: return ARM_EQ;
 	case GE: return ARM_PL;
 	case LT: return ARM_MI;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_Zmode:
@@ -16985,7 +17003,7 @@
 	{
 	case NE: return ARM_NE;
 	case EQ: return ARM_EQ;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_Nmode:
@@ -16993,7 +17011,7 @@
 	{
 	case NE: return ARM_MI;
 	case EQ: return ARM_PL;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CCFPEmode:
@@ -17018,7 +17036,7 @@
 	  /* UNEQ and LTGT do not have a representation.  */
 	case UNEQ: /* Fall through.  */
 	case LTGT: /* Fall through.  */
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_SWPmode:
@@ -17034,7 +17052,7 @@
 	case GTU: return ARM_CC;
 	case LEU: return ARM_CS;
 	case LTU: return ARM_HI;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_Cmode:
@@ -17042,7 +17060,7 @@
 	{
 	case LTU: return ARM_CS;
 	case GEU: return ARM_CC;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_CZmode:
@@ -17054,7 +17072,7 @@
 	case GTU: return ARM_HI;
 	case LEU: return ARM_LS;
 	case LTU: return ARM_CC;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CC_NCVmode:
@@ -17064,7 +17082,7 @@
 	case LT: return ARM_LT;
 	case GEU: return ARM_CS;
 	case LTU: return ARM_CC;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
     case CCmode:
@@ -17080,10 +17098,10 @@
 	case GTU: return ARM_HI;
 	case LEU: return ARM_LS;
 	case LTU: return ARM_CC;
-	default: gcc_unreachable ();
+	default: return ARM_COND_INVALID;
 	}
 
-    default: gcc_unreachable ();
+    default: return ARM_COND_INVALID;
     }
 }
 
Index: config/arm/arm.h
===================================================================
--- config/arm/arm.h	(revision 168663)
+++ config/arm/arm.h	(working copy)
@@ -147,7 +147,8 @@
 typedef enum arm_cond_code
 {
   ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
-  ARM_HI, ARM_LS, ARM_GE, ARM_LT, ARM_GT, ARM_LE, ARM_AL, ARM_NV
+  ARM_HI, ARM_LS, ARM_GE, ARM_LT, ARM_GT, ARM_LE, ARM_AL, ARM_NV,
+  ARM_COND_INVALID
 }
 arm_cc;
 
Index: config/arm/arm-protos.h
===================================================================
--- config/arm/arm-protos.h	(revision 168663)
+++ config/arm/arm-protos.h	(working copy)
@@ -107,6 +107,7 @@
 extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
 extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,
 						       HOST_WIDE_INT);
+extern bool arm_valid_comparison_p (rtx);
 extern rtx arm_gen_compare_reg (RTX_CODE, rtx, rtx);
 extern rtx arm_gen_return_addr_mask (void);
 extern void arm_reload_in_hi (rtx *);
Index: config/arm/predicates.md
===================================================================
--- config/arm/predicates.md	(revision 168663)
+++ config/arm/predicates.md	(working copy)
@@ -242,10 +242,11 @@
 ;; True for integer comparisons and, if FP is active, for comparisons
 ;; other than LTGT or UNEQ.
 (define_special_predicate "arm_comparison_operator"
-  (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu")
-       (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT
-			 && (TARGET_FPA || TARGET_VFP)")
-            (match_code "unordered,ordered,unlt,unle,unge,ungt"))))
+  (and (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu")
+            (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT
+                              && (TARGET_FPA || TARGET_VFP)")
+                 (match_code "unordered,ordered,unlt,unle,unge,ungt")))
+       (match_test "arm_valid_comparison_p (op)")))
 
 (define_special_predicate "lt_ge_comparison_operator"
   (match_code "lt,ge"))
Index: testsuite/gcc.target/arm/20110112-1.c
===================================================================
--- testsuite/gcc.target/arm/20110112-1.c	(revision 0)
+++ testsuite/gcc.target/arm/20110112-1.c	(revision 0)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -march=armv7-a -mthumb" } */
+
+#include <limits.h>
+
+void small (char *dst)
+{
+  while (1)
+    {
+      long long y = (long long)(*dst) << 8;
+
+      if (y < INT_MIN)
+	*((int *) dst) = 0;
+      else
+	*((int *) dst) = 1;
+    }
+}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, ARM] ICE in get_arm_condition_code()
  2011-01-13  1:37 [patch, ARM] ICE in get_arm_condition_code() Chung-Lin Tang
@ 2011-01-13 11:33 ` Ramana Radhakrishnan
  2011-01-26  3:48 ` Chung-Lin Tang
  1 sibling, 0 replies; 5+ messages in thread
From: Ramana Radhakrishnan @ 2011-01-13 11:33 UTC (permalink / raw)
  To: Chung-Lin Tang; +Cc: gcc-patches, paul, rearnsha

On Thu, Jan 13, 2011 at 12:24 AM, Chung-Lin Tang
<cltang@codesourcery.com> wrote:
> Hi
> The report was on a 4.5 based compiler, but I verified it also occurs on
> current trunk, under Thumb-2.
>@@ -16942,6 +16943,23 @@
> static enum arm_cond_code
> get_arm_condition_code (rtx comparison)
> {
>+  enum arm_cond_code code = arm_comparison_to_cond_code (comparison);
>+  gcc_assert (code != ARM_COND_INVALID);
>+  return code;
>+}
>+
>+/* Tests if the comparison RTX is valid for ARM. */

Minor nits really that I spotted .

2 spaces after the end of a '.' before the end of comment.

>+/* Function that maps the relation between comparison RTX
>+   vs. ARM condition codes, */

s/,/. and the 2 spaces after the . rule apply.



cheers
Ramana

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch, ARM] ICE in get_arm_condition_code()
  2011-01-13  1:37 [patch, ARM] ICE in get_arm_condition_code() Chung-Lin Tang
  2011-01-13 11:33 ` Ramana Radhakrishnan
@ 2011-01-26  3:48 ` Chung-Lin Tang
  2011-03-07 14:10   ` Ping " Chung-Lin Tang
  1 sibling, 1 reply; 5+ messages in thread
From: Chung-Lin Tang @ 2011-01-26  3:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: paul, rearnsha

Ping.
(I'll fix the minor nits before actually committing, thanks Ramana :)

On 2011/1/13 08:24, Chung-Lin Tang wrote:
> Hi,
> there's an ICE in arm.c:get_arm_condition_code(), from here:
> https://bugs.launchpad.net/gcc-linaro/+bug/689887
> 
> The report was on a 4.5 based compiler, but I verified it also occurs on
> current trunk, under Thumb-2.
> 
> The problem as I found, happens in RTL ifcvt after the combine pass.
> ifcvt.c:noce_emit_cmove() creates this:
> (insn 58 57 59 4 (parallel [
>             (set (reg:CC_NCV 24 cc)
>                 (compare:CC_NCV (reg:DI 140)
>                     (reg:DI 147)))
>             (clobber (scratch:SI))
>         ]) p.c:13 202 {*arm_cmpdi_insn}
>      (nil))
> 
> (insn 59 58 60 4 (set (reg:SI 146)
> 	(if_then_else:SI (gt (reg:CC_NCV 24 cc)
>                 (const_int 0 [0]))
>             (reg:SI 145)
>             (reg:SI 144))) p.c:13 701 {*thumb2_movsicc_insn}
>      (nil))
> 
> which is wrong; the GT comparison requires testing of the Z, C, and V
> flags, which CC_NCV does not satisfy. The ICE happens later when the asm
> emitting actually hits assert fail in get_arm_condition_code().
> 
> This patch fixes this by stratifying the "arm_comparison_operator"
> predicate, by leveraging the current logic in get_arm_condition_code().
> I abstracted out the body into a new arm_comparison_to_cond_code()
> function, which returns an invalid code instead of assert fail, and used
> it to add a check to the comparison RTX in "arm_comparison_operator".
> This way, invalid comparisons like the above would be blocked from emitting.
> 
> Tests were run with no regressions found. Okay for trunk?
> 
> Thanks,
> Chung-Lin
> 
> 2011-01-12  Chung-Lin Tang  <cltang@codesourcery.com>
> 
>         * config/arm/arm.h (enum arm_cond_code): Add ARM_COND_INVALID.
>         * config/arm/arm.c (arm_comparison_to_cond_code): Renamed from
>         get_arm_condition_code(), change gcc_unreachable()s to return
>         ARM_COND_INVALID.
>         (get_arm_condition_code): Implement by calling
>         arm_comparison_to_cond_code(), with result test by gcc_assert().
>         (arm_valid_comparison_p): New function to test for valid ARM
>         comparison RTX.
>         * config/arm/arm-protos.h (arm_valid_comparison_p): Add
> 	prototype.
>         * config/arm/predicates.md (arm_comparison_operator): Add
> 	additional check based on arm_valid_comparison_p().
> 
>         testsuite/
>         * gcc.target/arm/20110112-1.c: New test.
> 
> 
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Ping Re: [patch, ARM] ICE in get_arm_condition_code()
  2011-01-26  3:48 ` Chung-Lin Tang
@ 2011-03-07 14:10   ` Chung-Lin Tang
  2011-03-15  1:40     ` Ping^3 " Chung-Lin Tang
  0 siblings, 1 reply; 5+ messages in thread
From: Chung-Lin Tang @ 2011-03-07 14:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: paul, rearnsha

Ping.

On 2011/1/26 11:09 AM, Chung-Lin Tang wrote:
> Ping.
> (I'll fix the minor nits before actually committing, thanks Ramana :)
> 
> On 2011/1/13 08:24, Chung-Lin Tang wrote:
>> Hi,
>> there's an ICE in arm.c:get_arm_condition_code(), from here:
>> https://bugs.launchpad.net/gcc-linaro/+bug/689887
>>
>> The report was on a 4.5 based compiler, but I verified it also occurs on
>> current trunk, under Thumb-2.
>>
>> The problem as I found, happens in RTL ifcvt after the combine pass.
>> ifcvt.c:noce_emit_cmove() creates this:
>> (insn 58 57 59 4 (parallel [
>>             (set (reg:CC_NCV 24 cc)
>>                 (compare:CC_NCV (reg:DI 140)
>>                     (reg:DI 147)))
>>             (clobber (scratch:SI))
>>         ]) p.c:13 202 {*arm_cmpdi_insn}
>>      (nil))
>>
>> (insn 59 58 60 4 (set (reg:SI 146)
>> 	(if_then_else:SI (gt (reg:CC_NCV 24 cc)
>>                 (const_int 0 [0]))
>>             (reg:SI 145)
>>             (reg:SI 144))) p.c:13 701 {*thumb2_movsicc_insn}
>>      (nil))
>>
>> which is wrong; the GT comparison requires testing of the Z, C, and V
>> flags, which CC_NCV does not satisfy. The ICE happens later when the asm
>> emitting actually hits assert fail in get_arm_condition_code().
>>
>> This patch fixes this by stratifying the "arm_comparison_operator"
>> predicate, by leveraging the current logic in get_arm_condition_code().
>> I abstracted out the body into a new arm_comparison_to_cond_code()
>> function, which returns an invalid code instead of assert fail, and used
>> it to add a check to the comparison RTX in "arm_comparison_operator".
>> This way, invalid comparisons like the above would be blocked from emitting.
>>
>> Tests were run with no regressions found. Okay for trunk?
>>
>> Thanks,
>> Chung-Lin
>>
>> 2011-01-12  Chung-Lin Tang  <cltang@codesourcery.com>
>>
>>         * config/arm/arm.h (enum arm_cond_code): Add ARM_COND_INVALID.
>>         * config/arm/arm.c (arm_comparison_to_cond_code): Renamed from
>>         get_arm_condition_code(), change gcc_unreachable()s to return
>>         ARM_COND_INVALID.
>>         (get_arm_condition_code): Implement by calling
>>         arm_comparison_to_cond_code(), with result test by gcc_assert().
>>         (arm_valid_comparison_p): New function to test for valid ARM
>>         comparison RTX.
>>         * config/arm/arm-protos.h (arm_valid_comparison_p): Add
>> 	prototype.
>>         * config/arm/predicates.md (arm_comparison_operator): Add
>> 	additional check based on arm_valid_comparison_p().
>>
>>         testsuite/
>>         * gcc.target/arm/20110112-1.c: New test.
>>
>>
>>
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Ping^3 Re: [patch, ARM] ICE in get_arm_condition_code()
  2011-03-07 14:10   ` Ping " Chung-Lin Tang
@ 2011-03-15  1:40     ` Chung-Lin Tang
  0 siblings, 0 replies; 5+ messages in thread
From: Chung-Lin Tang @ 2011-03-15  1:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: paul, rearnsha

Ping.

On 2011/3/7 10:10 PM, Chung-Lin Tang wrote:
> Ping.
> 
> On 2011/1/26 11:09 AM, Chung-Lin Tang wrote:
>> Ping.
>> (I'll fix the minor nits before actually committing, thanks Ramana :)
>>
>> On 2011/1/13 08:24, Chung-Lin Tang wrote:
>>> Hi,
>>> there's an ICE in arm.c:get_arm_condition_code(), from here:
>>> https://bugs.launchpad.net/gcc-linaro/+bug/689887
>>>
>>> The report was on a 4.5 based compiler, but I verified it also occurs on
>>> current trunk, under Thumb-2.
>>>
>>> The problem as I found, happens in RTL ifcvt after the combine pass.
>>> ifcvt.c:noce_emit_cmove() creates this:
>>> (insn 58 57 59 4 (parallel [
>>>             (set (reg:CC_NCV 24 cc)
>>>                 (compare:CC_NCV (reg:DI 140)
>>>                     (reg:DI 147)))
>>>             (clobber (scratch:SI))
>>>         ]) p.c:13 202 {*arm_cmpdi_insn}
>>>      (nil))
>>>
>>> (insn 59 58 60 4 (set (reg:SI 146)
>>> 	(if_then_else:SI (gt (reg:CC_NCV 24 cc)
>>>                 (const_int 0 [0]))
>>>             (reg:SI 145)
>>>             (reg:SI 144))) p.c:13 701 {*thumb2_movsicc_insn}
>>>      (nil))
>>>
>>> which is wrong; the GT comparison requires testing of the Z, C, and V
>>> flags, which CC_NCV does not satisfy. The ICE happens later when the asm
>>> emitting actually hits assert fail in get_arm_condition_code().
>>>
>>> This patch fixes this by stratifying the "arm_comparison_operator"
>>> predicate, by leveraging the current logic in get_arm_condition_code().
>>> I abstracted out the body into a new arm_comparison_to_cond_code()
>>> function, which returns an invalid code instead of assert fail, and used
>>> it to add a check to the comparison RTX in "arm_comparison_operator".
>>> This way, invalid comparisons like the above would be blocked from emitting.
>>>
>>> Tests were run with no regressions found. Okay for trunk?
>>>
>>> Thanks,
>>> Chung-Lin
>>>
>>> 2011-01-12  Chung-Lin Tang  <cltang@codesourcery.com>
>>>
>>>         * config/arm/arm.h (enum arm_cond_code): Add ARM_COND_INVALID.
>>>         * config/arm/arm.c (arm_comparison_to_cond_code): Renamed from
>>>         get_arm_condition_code(), change gcc_unreachable()s to return
>>>         ARM_COND_INVALID.
>>>         (get_arm_condition_code): Implement by calling
>>>         arm_comparison_to_cond_code(), with result test by gcc_assert().
>>>         (arm_valid_comparison_p): New function to test for valid ARM
>>>         comparison RTX.
>>>         * config/arm/arm-protos.h (arm_valid_comparison_p): Add
>>> 	prototype.
>>>         * config/arm/predicates.md (arm_comparison_operator): Add
>>> 	additional check based on arm_valid_comparison_p().
>>>
>>>         testsuite/
>>>         * gcc.target/arm/20110112-1.c: New test.
>>>
>>>
>>>
>>
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-03-15  1:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-13  1:37 [patch, ARM] ICE in get_arm_condition_code() Chung-Lin Tang
2011-01-13 11:33 ` Ramana Radhakrishnan
2011-01-26  3:48 ` Chung-Lin Tang
2011-03-07 14:10   ` Ping " Chung-Lin Tang
2011-03-15  1:40     ` Ping^3 " Chung-Lin Tang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).