[ARC] Fix unwanted match for sign extend 16-bit constant.
authorClaudiu Zissulescu <claziss@synopsys.com>
Fri, 29 Apr 2016 08:39:22 +0000 (10:39 +0200)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Fri, 29 Apr 2016 08:39:22 +0000 (10:39 +0200)
The combine pass may conclude umulhisi3_imm pattern can accept also sign
extended 16-bit constants. This patch prohibits the combine in considering
this pattern as suitable.

gcc/
2016-04-29  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.h (UNSIGNED_INT12, UNSIGNED_INT16): Define.
* config/arc/arc.md (umulhisi3): Use arc_short_operand predicate.
(umulhisi3_imm): Update predicates and constraint letters.
(umulhisi3_reg): Declare instruction as commutative.
* config/arc/constraints.md (J12, J16): New constraints.
* config/arc/predicates.md (short_unsigned_const_operand): New
predicate.
(arc_short_operand): Likewise.
* testsuite/gcc.target/arc/umulsihi3_z.c: New file.

From-SVN: r235623

gcc/ChangeLog
gcc/config/arc/arc.h
gcc/config/arc/arc.md
gcc/config/arc/constraints.md
gcc/config/arc/predicates.md
gcc/testsuite/gcc.target/arc/umulsihi3_z.c [new file with mode: 0644]

index 0e7055614c6348d0b98a00bcce90804af39dbeb9..a92fd768eeeb3fd660f5a473fc17c73574ef03c5 100644 (file)
@@ -1,3 +1,15 @@
+2016-04-29  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.h (UNSIGNED_INT12, UNSIGNED_INT16): Define.
+       * config/arc/arc.md (umulhisi3): Use arc_short_operand predicate.
+       (umulhisi3_imm): Update predicates and constraint letters.
+       (umulhisi3_reg): Declare instruction as commutative.
+       * config/arc/constraints.md (J12, J16): New constraints.
+       * config/arc/predicates.md (short_unsigned_const_operand): New
+       predicate.
+       (arc_short_operand): Likewise.
+       * testsuite/gcc.target/arc/umulsihi3_z.c: New file.
+
 2016-04-29  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/13962
index 4235eabc96d38a57d1dba86d3a867b5b017250f9..bc14d11ab1f9b98ad2fa51d99549b7de6282199e 100644 (file)
@@ -815,6 +815,8 @@ extern enum reg_class arc_regno_reg_class[];
 #define UNSIGNED_INT6(X) ((unsigned) (X) < 0x40)
 #define UNSIGNED_INT7(X) ((unsigned) (X) < 0x80)
 #define UNSIGNED_INT8(X) ((unsigned) (X) < 0x100)
+#define UNSIGNED_INT12(X) ((unsigned) (X) < 0x800)
+#define UNSIGNED_INT16(X) ((unsigned) (X) < 0x10000)
 #define IS_ONE(X) ((X) == 1)
 #define IS_ZERO(X) ((X) == 0)
 
index 7c30eb46e072448a7e45ad79b584f070f893058b..d1a9159411da268e12eb5a54a2f9621720a4c015 100644 (file)
 (define_expand "umulhisi3"
   [(set (match_operand:SI 0 "register_operand"                           "")
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand"  ""))
-                (zero_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
+                (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
   "TARGET_MPYW"
   "{
     if (CONSTANT_P (operands[2]))
 )
 
 (define_insn "umulhisi3_imm"
-  [(set (match_operand:SI 0 "register_operand"                          "=r, r,r,  r,  r")
-       (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " 0, r,0,  0,  r"))
-                (match_operand:HI 2 "short_const_int_operand"          " L, L,I,C16,C16")))]
+  [(set (match_operand:SI 0 "register_operand"                          "=r, r,  r,  r,  r")
+       (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r,  0,  0,  r"))
+                (match_operand:HI 2 "short_unsigned_const_operand"     " L, L,J12,J16,J16")))]
   "TARGET_MPYW"
   "mpyuw%? %0,%1,%2"
   [(set_attr "length" "4,4,4,8,8")
 
 (define_insn "umulhisi3_reg"
   [(set (match_operand:SI 0 "register_operand"                          "=Rcqq, r, r")
-       (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "    0, 0, r"))
+       (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "   %0, 0, r"))
                 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
   "TARGET_MPYW"
   "mpyuw%? %0,%1,%2"
index f30572c48579dbdcdcacae1c11ba83e13d15fe29..5069d7d9746de3dbd7621a755a7435fdf70b168f 100644 (file)
 (define_memory_constraint "ATO"
   "A memory with only a base register"
   (match_operand 0 "mem_noofs_operand"))
+
+(define_constraint "J12"
+  "@internal
+   An unsigned 12-bit integer constant."
+  (and (match_code "const_int")
+       (match_test "UNSIGNED_INT12 (ival)")))
+
+(define_constraint "J16"
+  "@internal
+   An unsigned 16-bit integer constant"
+  (and (match_code "const_int")
+       (match_test "UNSIGNED_INT16 (ival)")))
index 0d2e217bf9d66750548c4350dbdb71a83f748285..8e4b4b40c543c46b471715664322f7acdf2c4858 100644 (file)
   (ior (match_operand:SI 0 "cmem_address_0")
        (match_operand:SI 0 "cmem_address_1")
        (match_operand:SI 0 "cmem_address_2")))
+
+(define_predicate "short_unsigned_const_operand"
+  (and (match_code "const_int")
+       (match_test "satisfies_constraint_J16 (op)")))
+
+(define_predicate "arc_short_operand"
+  (ior (match_test "register_operand (op, mode)")
+       (match_test "short_unsigned_const_operand (op, mode)")))
diff --git a/gcc/testsuite/gcc.target/arc/umulsihi3_z.c b/gcc/testsuite/gcc.target/arc/umulsihi3_z.c
new file mode 100644 (file)
index 0000000..cf1c00d
--- /dev/null
@@ -0,0 +1,23 @@
+/* Check if the optimizers are not removing the umulsihi3_imm
+   instruction.  */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-inline" } */
+
+#include <stdint.h>
+
+static int32_t test (int16_t reg_val)
+{
+  int32_t x = (reg_val & 0xf) * 62500;
+  return x;
+}
+
+int main (void)
+{
+  volatile int32_t x = 0xc172;
+  x = test (x);
+
+  if (x != 0x0001e848)
+    __builtin_abort ();
+  return 0;
+}
+