re PR target/49030 (ICE in get_arm_condition_code, at config/arm/arm.c:17180)
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 7 Sep 2011 13:48:03 +0000 (13:48 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 7 Sep 2011 13:48:03 +0000 (13:48 +0000)
gcc/
PR target/49030
* config/arm/arm-protos.h (maybe_get_arm_condition_code): Declare.
* config/arm/arm.c (maybe_get_arm_condition_code): New function,
reusing the old code from get_arm_condition_code.  Return ARM_NV
for invalid comparison codes.
(get_arm_condition_code): Redefine in terms of
maybe_get_arm_condition_code.
* config/arm/predicates.md (arm_comparison_operator): Use
maybe_get_arm_condition_code.

gcc/testsuite/
PR target/49030
* gcc.dg/torture/pr49030.c: New test.

From-SVN: r178636

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr49030.c [new file with mode: 0644]

index 5cde3b1dcf0301019e8a554e0b467e4ab0cac23d..64ae69e4c46fcd204dd86672ea49cd0700140552 100644 (file)
@@ -1,3 +1,15 @@
+2011-09-07  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR target/49030
+       * config/arm/arm-protos.h (maybe_get_arm_condition_code): Declare.
+       * config/arm/arm.c (maybe_get_arm_condition_code): New function,
+       reusing the old code from get_arm_condition_code.  Return ARM_NV
+       for invalid comparison codes.
+       (get_arm_condition_code): Redefine in terms of
+       maybe_get_arm_condition_code.
+       * config/arm/predicates.md (arm_comparison_operator): Use
+       maybe_get_arm_condition_code.
+
 2011-09-07  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
index 4093c5688c4211a98d315c4fef073c2d03092476..9030e96052eff6cbba82199a463e6412d0eff8dd 100644 (file)
@@ -184,6 +184,7 @@ extern int is_called_in_ARM_mode (tree);
 #endif
 extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
 #ifdef RTX_CODE
+extern enum arm_cond_code maybe_get_arm_condition_code (rtx);
 extern void thumb1_final_prescan_insn (rtx);
 extern void thumb2_final_prescan_insn (rtx);
 extern const char *thumb_load_double_from_address (rtx *);
index 0a1a6518a1c3082363a4703514d166125321a0ac..6311612a6cd21914cc094cfbd0701edb81a2a67c 100644 (file)
@@ -17595,10 +17595,10 @@ arm_elf_asm_destructor (rtx symbol, int priority)
    decremented/zeroed by arm_asm_output_opcode as the insns are output.  */
 
 /* Returns the index of the ARM condition code string in
-   `arm_condition_codes'.  COMPARISON should be an rtx like
-   `(eq (...) (...))'.  */
-static enum arm_cond_code
-get_arm_condition_code (rtx comparison)
+   `arm_condition_codes', or ARM_NV if the comparison is invalid.
+   COMPARISON should be an rtx like `(eq (...) (...))'.  */
+enum arm_cond_code
+maybe_get_arm_condition_code (rtx comparison)
 {
   enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
   enum arm_cond_code code;
@@ -17622,11 +17622,11 @@ get_arm_condition_code (rtx comparison)
     case CC_DLTUmode: code = ARM_CC;
 
     dominance:
-      gcc_assert (comp_code == EQ || comp_code == NE);
-
       if (comp_code == EQ)
        return ARM_INVERSE_CONDITION_CODE (code);
-      return code;
+      if (comp_code == NE)
+       return code;
+      return ARM_NV;
 
     case CC_NOOVmode:
       switch (comp_code)
@@ -17635,7 +17635,7 @@ get_arm_condition_code (rtx comparison)
        case EQ: return ARM_EQ;
        case GE: return ARM_PL;
        case LT: return ARM_MI;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_Zmode:
@@ -17643,7 +17643,7 @@ get_arm_condition_code (rtx comparison)
        {
        case NE: return ARM_NE;
        case EQ: return ARM_EQ;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_Nmode:
@@ -17651,7 +17651,7 @@ get_arm_condition_code (rtx comparison)
        {
        case NE: return ARM_MI;
        case EQ: return ARM_PL;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CCFPEmode:
@@ -17676,7 +17676,7 @@ get_arm_condition_code (rtx comparison)
          /* UNEQ and LTGT do not have a representation.  */
        case UNEQ: /* Fall through.  */
        case LTGT: /* Fall through.  */
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_SWPmode:
@@ -17692,7 +17692,7 @@ get_arm_condition_code (rtx comparison)
        case GTU: return ARM_CC;
        case LEU: return ARM_CS;
        case LTU: return ARM_HI;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_Cmode:
@@ -17700,7 +17700,7 @@ get_arm_condition_code (rtx comparison)
        {
        case LTU: return ARM_CS;
        case GEU: return ARM_CC;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_CZmode:
@@ -17712,7 +17712,7 @@ get_arm_condition_code (rtx comparison)
        case GTU: return ARM_HI;
        case LEU: return ARM_LS;
        case LTU: return ARM_CC;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CC_NCVmode:
@@ -17722,7 +17722,7 @@ get_arm_condition_code (rtx comparison)
        case LT: return ARM_LT;
        case GEU: return ARM_CS;
        case LTU: return ARM_CC;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     case CCmode:
@@ -17738,13 +17738,22 @@ get_arm_condition_code (rtx comparison)
        case GTU: return ARM_HI;
        case LEU: return ARM_LS;
        case LTU: return ARM_CC;
-       default: gcc_unreachable ();
+       default: return ARM_NV;
        }
 
     default: gcc_unreachable ();
     }
 }
 
+/* Like maybe_get_arm_condition_code, but never return ARM_NV.  */
+static enum arm_cond_code
+get_arm_condition_code (rtx comparison)
+{
+  enum arm_cond_code code = maybe_get_arm_condition_code (comparison);
+  gcc_assert (code != ARM_NV);
+  return code;
+}
+
 /* Tell arm_asm_output_opcode to output IT blocks for conditionally executed
    instructions.  */
 void
index cfe8d33696d98e6c77d1d5ac022cd3fe6d69d5b8..c7d6206b138e5f84db68004d4d88d4f59149321d 100644 (file)
 ;; 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 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
+                   unordered,ordered,unlt,unle,unge,ungt")
+       (match_test "maybe_get_arm_condition_code (op) != ARM_NV")))
 
 (define_special_predicate "lt_ge_comparison_operator"
   (match_code "lt,ge"))
index 322f81738a98e3e049e39326395b5ab7cde184ac..c5433a4dcf0607a777d1f30522eb527153f41af5 100644 (file)
@@ -1,3 +1,8 @@
+2011-09-07  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR target/49030
+       * gcc.dg/torture/pr49030.c: New test.
+
 2011-09-07  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/50288
diff --git a/gcc/testsuite/gcc.dg/torture/pr49030.c b/gcc/testsuite/gcc.dg/torture/pr49030.c
new file mode 100644 (file)
index 0000000..4b078a9
--- /dev/null
@@ -0,0 +1,19 @@
+void
+sample_move_d32u24_sS (char *dst, float *src, unsigned long nsamples,
+                      unsigned long dst_skip)
+{
+  long long y;
+  while (nsamples--)
+    {
+      y = (long long) (*src * 8388608.0f) << 8;
+      if (y > 2147483647) {
+       *(int *) dst = 2147483647;
+      } else if (y < -2147483647 - 1) {
+       *(int *) dst = -2147483647 - 1;
+      } else {
+       *(int *) dst = (int) y;
+      }
+      dst += dst_skip;
+      src++;
+    }
+}