aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386.md27
-rw-r--r--gcc/testsuite/gcc.target/i386/divmod-9.c14
2 files changed, 40 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 26fb81b..8b809c4 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8385,7 +8385,7 @@
(ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
(parallel [(set (match_dup 0)
- (div:SWIM248 (match_dup 2) (match_dup 3)))
+ (div:SWIM248 (match_dup 2) (match_dup 3)))
(set (match_dup 1)
(mod:SWIM248 (match_dup 2) (match_dup 3)))
(use (match_dup 1))
@@ -8661,6 +8661,31 @@
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
+;; Avoid sign-extension (using cdq) for constant numerators.
+(define_insn_and_split "*divmodsi4_const"
+ [(set (match_operand:SI 0 "register_operand" "=&a")
+ (div:SI (match_operand:SI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SI 1 "register_operand" "=&d")
+ (mod:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "!optimize_function_for_size_p (cfun)"
+ "#"
+ "reload_completed"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 1) (match_dup 4))
+ (parallel [(set (match_dup 0)
+ (div:SI (match_dup 0) (match_dup 3)))
+ (set (match_dup 1)
+ (mod:SI (match_dup 0) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
(define_expand "divmodqi4"
[(parallel [(set (match_operand:QI 0 "register_operand")
(div:QI
diff --git a/gcc/testsuite/gcc.target/i386/divmod-9.c b/gcc/testsuite/gcc.target/i386/divmod-9.c
new file mode 100644
index 0000000..1515e69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/divmod-9.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int foo (int x)
+{
+ return 100/x;
+}
+
+int bar(int x)
+{
+ return -100/x;
+}
+/* { dg-final { scan-assembler-not "(cltd|cdq)" } } */
+