[ARM] PR target/64600 Fix another ICE with -mtune=xscale: properly sign-extend mask...
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Fri, 13 Mar 2015 10:48:44 +0000 (10:48 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Fri, 13 Mar 2015 10:48:44 +0000 (10:48 +0000)
PR target/64600
* config/arm/arm.c (arm_gen_constant, AND case): Use
ARM_SIGN_EXTEND when constructing AND mask.

PR target/64600
* gcc.target/arm/pr64600_1.c: New test.

From-SVN: r221413

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr64600_1.c [new file with mode: 0644]

index eb5a2d9fc8d29b5f233d3a84ac4cbe22b1cf4a59..8a24aecda88fc670038a3b915ab8e3b55280b492 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/64600
+       * config/arm/arm.c (arm_gen_constant, AND case): Use
+       ARM_SIGN_EXTEND when constructing AND mask.
+
 2015-03-13  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * graph.c (print_graph_cfg): Make function names visible and append
index 48342d0c0ec7ffcef123f6f7c162001bbdaebead..8e484a20377c0c53fce5a1c04e8c46d13fc0859d 100644 (file)
@@ -4536,19 +4536,20 @@ arm_gen_constant (enum rtx_code code, machine_mode mode, rtx cond,
 
          if ((remainder | shift_mask) != 0xffffffff)
            {
+             HOST_WIDE_INT new_val
+               = ARM_SIGN_EXTEND (remainder | shift_mask);
+
              if (generate)
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
-                 insns = arm_gen_constant (AND, mode, cond,
-                                           remainder | shift_mask,
+                 insns = arm_gen_constant (AND, SImode, cond, new_val,
                                            new_src, source, subtargets, 1);
                  source = new_src;
                }
              else
                {
                  rtx targ = subtargets ? NULL_RTX : target;
-                 insns = arm_gen_constant (AND, mode, cond,
-                                           remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond, new_val,
                                            targ, source, subtargets, 0);
                }
            }
@@ -4571,12 +4572,13 @@ arm_gen_constant (enum rtx_code code, machine_mode mode, rtx cond,
 
          if ((remainder | shift_mask) != 0xffffffff)
            {
+             HOST_WIDE_INT new_val
+               = ARM_SIGN_EXTEND (remainder | shift_mask);
              if (generate)
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
 
-                 insns = arm_gen_constant (AND, mode, cond,
-                                           remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond, new_val,
                                            new_src, source, subtargets, 1);
                  source = new_src;
                }
@@ -4584,8 +4586,7 @@ arm_gen_constant (enum rtx_code code, machine_mode mode, rtx cond,
                {
                  rtx targ = subtargets ? NULL_RTX : target;
 
-                 insns = arm_gen_constant (AND, mode, cond,
-                                           remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond, new_val,
                                            targ, source, subtargets, 0);
                }
            }
index 4a776eec092dc9d782fc84d6b64b551ab2483555..152d36cf77f4b90980722c0316c11ae1a1dfd591 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/64600
+       * gcc.target/arm/pr64600_1.c: New test.
+
 2015-03-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR rtl-optimization/65235
diff --git a/gcc/testsuite/gcc.target/arm/pr64600_1.c b/gcc/testsuite/gcc.target/arm/pr64600_1.c
new file mode 100644 (file)
index 0000000..6ba3fa2
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=xscale" } */
+
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+struct termios {
+ tcflag_t c_cflag;
+};
+
+speed_t
+cfgetospeed (const struct termios *tp)
+{
+  return tp->c_cflag & 010017;
+}