* [PATCH, i386]: Macroize DIVMOD patterns
@ 2019-05-14 16:22 Uros Bizjak
2019-05-15 12:16 ` Richard Biener
0 siblings, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2019-05-14 16:22 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1427 bytes --]
Recent work by Richard Sandiford [1] enabled the possibility to
macroize DIVMOD patterns in i386.md.
2019-05-14 Uroš Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (any_div): New code iterator.
(paired_mod): New code attribute.
(sgnprefix): Handle DIV and UDIV RTXes.
(u): Ditto.
(<u>divmod<mode>4): Macroize expander from divmod<mode>4
and udivmod<mode>4 patterns using any_div code iterator.
(divmod splitters): Macroize splitters using any_div code iterator.
(*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition.
(*udivmodsi4_pow2_zext_2): Ditto.
(*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
and *udivmod<mode>4_noext patterns using any_div code iterator.
(*<u>divmod<mode>4_noext_zext_1): Macroize insn from
*divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
patterns using any_div code iterator.
(*<u>divmod<mode>4_noext_zext_2): Macroize insn from
*divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
patterns using any_div code iterator.
(<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
udivmodhiqi3 patterns using any_extend code iterator.
The patch also reorders DIVMOD patterns a bit.
Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
Committed to mainline SVN.
[1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html
Uros.
[-- Attachment #2: p.diff.txt --]
[-- Type: text/plain, Size: 29160 bytes --]
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index edec0ab0386c..05411221197f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -933,11 +933,12 @@
(define_code_iterator any_extend [sign_extend zero_extend])
;; Prefix for insn menmonic.
-(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
-
+(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
+ (div "i") (udiv "")])
;; Prefix for define_insn
-(define_code_attr u [(sign_extend "") (zero_extend "u")])
(define_code_attr s [(sign_extend "s") (zero_extend "u")])
+(define_code_attr u [(sign_extend "") (zero_extend "u")
+ (div "") (udiv "u")])
(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
;; Used in signed and unsigned truncations.
@@ -7475,13 +7476,16 @@
\f
;; Divmod instructions.
-(define_expand "divmod<mode>4"
+(define_code_iterator any_div [div udiv])
+(define_code_attr paired_mod [(div "mod") (udiv "umod")])
+
+(define_expand "<u>divmod<mode>4"
[(parallel [(set (match_operand:SWIM248 0 "register_operand")
- (div:SWIM248
+ (any_div:SWIM248
(match_operand:SWIM248 1 "register_operand")
(match_operand:SWIM248 2 "nonimmediate_operand")))
(set (match_operand:SWIM248 3 "register_operand")
- (mod:SWIM248 (match_dup 1) (match_dup 2)))
+ (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])])
;; Split with 8bit unsigned divide:
@@ -7491,10 +7495,10 @@
;; use original integer divide
(define_split
[(set (match_operand:SWI48 0 "register_operand")
- (div:SWI48 (match_operand:SWI48 2 "register_operand")
- (match_operand:SWI48 3 "nonimmediate_operand")))
+ (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
+ (match_operand:SWI48 3 "nonimmediate_operand")))
(set (match_operand:SWI48 1 "register_operand")
- (mod:SWI48 (match_dup 2) (match_dup 3)))
+ (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_USE_8BIT_IDIV
&& TARGET_QIMODE_MATH
@@ -7506,12 +7510,13 @@
(define_split
[(set (match_operand:DI 0 "register_operand")
(zero_extend:DI
- (div:SI (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "nonimmediate_operand"))))
+ (any_div:SI (match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "nonimmediate_operand"))))
(set (match_operand:SI 1 "register_operand")
- (mod:SI (match_dup 2) (match_dup 3)))
+ (<paired_mod>:SI (match_dup 2) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_8BIT_IDIV
+ "TARGET_64BIT
+ && TARGET_USE_8BIT_IDIV
&& TARGET_QIMODE_MATH
&& can_create_pseudo_p ()
&& !optimize_insn_for_size_p ()"
@@ -7521,12 +7526,13 @@
(define_split
[(set (match_operand:DI 1 "register_operand")
(zero_extend:DI
- (mod:SI (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "nonimmediate_operand"))))
+ (<paired_mod>:SI (match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "nonimmediate_operand"))))
(set (match_operand:SI 0 "register_operand")
- (div:SI (match_dup 2) (match_dup 3)))
+ (any_div:SI (match_dup 2) (match_dup 3)))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_8BIT_IDIV
+ "TARGET_64BIT
+ && TARGET_USE_8BIT_IDIV
&& TARGET_QIMODE_MATH
&& can_create_pseudo_p ()
&& !optimize_insn_for_size_p ()"
@@ -7568,6 +7574,28 @@
[(set_attr "type" "multi")
(set_attr "mode" "<MODE>")])
+(define_insn_and_split "udivmod<mode>4_1"
+ [(set (match_operand:SWI48 0 "register_operand" "=a")
+ (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
+ (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SWI48 1 "register_operand" "=&d")
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (match_dup 1) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (udiv:SWI48 (match_dup 2) (match_dup 3)))
+ (set (match_dup 1)
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+ ""
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
+
(define_insn_and_split "divmodsi4_zext_1"
[(set (match_operand:DI 0 "register_operand" "=a")
(zero_extend:DI
@@ -7579,7 +7607,7 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
- "reload_completed"
+ "&& reload_completed"
[(parallel [(set (match_dup 1)
(ashiftrt:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
@@ -7604,6 +7632,29 @@
[(set_attr "type" "multi")
(set_attr "mode" "SI")])
+(define_insn_and_split "udivmodsi4_zext_1"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (zero_extend:DI
+ (udiv:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (set (match_operand:SI 1 "register_operand" "=&d")
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 1) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
+ (set (match_dup 1)
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+ ""
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
(define_insn_and_split "divmodsi4_zext_2"
[(set (match_operand:DI 1 "register_operand" "=&d")
(zero_extend:DI
@@ -7615,7 +7666,7 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
- "reload_completed"
+ "&& reload_completed"
[(parallel [(set (match_dup 6)
(ashiftrt:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
@@ -7641,6 +7692,29 @@
[(set_attr "type" "multi")
(set_attr "mode" "SI")])
+(define_insn_and_split "udivmodsi4_zext_2"
+ [(set (match_operand:DI 1 "register_operand" "=&d")
+ (zero_extend:DI
+ (umod:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (set (match_operand:SI 0 "register_operand" "=a")
+ (udiv:SI (match_dup 2) (match_dup 3)))
+ (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (const_int 0))
+ (parallel [(set (match_dup 1)
+ (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
+ (set (match_dup 0)
+ (udiv:SI (match_dup 2) (match_dup 3)))
+ (use (match_dup 4))
+ (clobber (reg:CC FLAGS_REG))])]
+ "operands[4] = gen_lowpart (SImode, operands[1]);"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
(define_insn_and_split "*divmod<mode>4"
[(set (match_operand:SWIM248 0 "register_operand" "=a")
(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
@@ -7676,6 +7750,52 @@
[(set_attr "type" "multi")
(set_attr "mode" "<MODE>")])
+(define_insn_and_split "*udivmod<mode>4"
+ [(set (match_operand:SWIM248 0 "register_operand" "=a")
+ (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
+ (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
+ (set (match_operand:SWIM248 1 "register_operand" "=&d")
+ (umod:SWIM248 (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (match_dup 1) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (udiv:SWIM248 (match_dup 2) (match_dup 3)))
+ (set (match_dup 1)
+ (umod:SWIM248 (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+ ""
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
+
+;; Optimize division or modulo by constant power of 2, if the constant
+;; materializes only after expansion.
+(define_insn_and_split "*udivmod<mode>4_pow2"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
+ (match_operand:SWI48 3 "const_int_operand" "n")))
+ (set (match_operand:SWI48 1 "register_operand" "=r")
+ (umod:SWI48 (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 1) (match_dup 2))
+ (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ int v = exact_log2 (UINTVAL (operands[3]));
+ operands[4] = GEN_INT (v);
+ operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
+
(define_insn_and_split "*divmodsi4_zext_1"
[(set (match_operand:DI 0 "register_operand" "=a")
(zero_extend:DI
@@ -7686,7 +7806,7 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
- "reload_completed"
+ "&& reload_completed"
[(parallel [(set (match_dup 1)
(ashiftrt:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
@@ -7711,6 +7831,54 @@
[(set_attr "type" "multi")
(set_attr "mode" "SI")])
+(define_insn_and_split "*udivmodsi4_zext_1"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (zero_extend:DI
+ (udiv:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (set (match_operand:SI 1 "register_operand" "=&d")
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 1) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
+ (set (match_dup 1)
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (use (match_dup 1))
+ (clobber (reg:CC FLAGS_REG))])]
+ ""
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
+(define_insn_and_split "*udivmodsi4_pow2_zext_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (udiv:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "const_int_operand" "n"))))
+ (set (match_operand:SI 1 "register_operand" "=r")
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT
+ && exact_log2 (UINTVAL (operands[3])) > 0"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 1) (match_dup 2))
+ (parallel [(set (match_dup 0)
+ (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ int v = exact_log2 (UINTVAL (operands[3]));
+ operands[4] = GEN_INT (v);
+ operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
(define_insn_and_split "*divmodsi4_zext_2"
[(set (match_operand:DI 1 "register_operand" "=&d")
(zero_extend:DI
@@ -7721,7 +7889,7 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
- "reload_completed"
+ "&& reload_completed"
[(parallel [(set (match_dup 6)
(ashiftrt:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])
@@ -7747,44 +7915,93 @@
[(set_attr "type" "multi")
(set_attr "mode" "SI")])
-(define_insn "*divmod<mode>4_noext"
+(define_insn_and_split "*udivmodsi4_zext_2"
+ [(set (match_operand:DI 1 "register_operand" "=&d")
+ (zero_extend:DI
+ (umod:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (set (match_operand:SI 0 "register_operand" "=a")
+ (udiv:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (const_int 0))
+ (parallel [(set (match_dup 1)
+ (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
+ (set (match_dup 0)
+ (udiv:SI (match_dup 2) (match_dup 3)))
+ (use (match_dup 4))
+ (clobber (reg:CC FLAGS_REG))])]
+ "operands[4] = gen_lowpart (SImode, operands[1]);"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
+(define_insn_and_split "*udivmodsi4_pow2_zext_2"
+ [(set (match_operand:DI 1 "register_operand" "=r")
+ (zero_extend:DI
+ (umod:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "const_int_operand" "n"))))
+ (set (match_operand:SI 0 "register_operand" "=r")
+ (umod:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT
+ && exact_log2 (UINTVAL (operands[3])) > 0"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 1) (match_dup 2))
+ (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_dup 1)
+ (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
+ (clobber (reg:CC FLAGS_REG))])]
+{
+ int v = exact_log2 (UINTVAL (operands[3]));
+ operands[4] = GEN_INT (v);
+ operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
+}
+ [(set_attr "type" "multi")
+ (set_attr "mode" "SI")])
+
+(define_insn "*<u>divmod<mode>4_noext"
[(set (match_operand:SWIM248 0 "register_operand" "=a")
- (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
+ (any_div:SWIM248
+ (match_operand:SWIM248 2 "register_operand" "0")
+ (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
(set (match_operand:SWIM248 1 "register_operand" "=d")
- (mod:SWIM248 (match_dup 2) (match_dup 3)))
+ (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
(use (match_operand:SWIM248 4 "register_operand" "1"))
(clobber (reg:CC FLAGS_REG))]
""
- "idiv{<imodesuffix>}\t%3"
+ "<sgnprefix>div{<imodesuffix>}\t%3"
[(set_attr "type" "idiv")
(set_attr "mode" "<MODE>")])
-(define_insn "*divmodsi4_noext_zext_1"
+(define_insn "*<u>divmodsi4_noext_zext_1"
[(set (match_operand:DI 0 "register_operand" "=a")
(zero_extend:DI
- (div:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (any_div:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
(set (match_operand:SI 1 "register_operand" "=d")
- (mod:SI (match_dup 2) (match_dup 3)))
+ (<paired_mod>:SI (match_dup 2) (match_dup 3)))
(use (match_operand:SI 4 "register_operand" "1"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
- "idiv{l}\t%3"
+ "<sgnprefix>div{l}\t%3"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
-(define_insn "*divmodsi4_noext_zext_2"
+(define_insn "*<u>divmodsi4_noext_zext_2"
[(set (match_operand:DI 1 "register_operand" "=d")
(zero_extend:DI
- (mod:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
+ (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
+ (match_operand:SI 3 "nonimmediate_operand" "rm"))))
(set (match_operand:SI 0 "register_operand" "=a")
- (div:SI (match_dup 2) (match_dup 3)))
+ (any_div:SI (match_dup 2) (match_dup 3)))
(use (match_operand:SI 4 "register_operand" "1"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
- "idiv{l}\t%3"
+ "<sgnprefix>div{l}\t%3"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
@@ -7800,7 +8017,7 @@
{
rtx div, mod;
rtx tmp0, tmp1;
-
+
tmp0 = gen_reg_rtx (HImode);
tmp1 = gen_reg_rtx (HImode);
@@ -7825,345 +8042,6 @@
DONE;
})
-;; Divide AX by r/m8, with result stored in
-;; AL <- Quotient
-;; AH <- Remainder
-;; Change div/mod to HImode and extend the second argument to HImode
-;; so that mode of div/mod matches with mode of arguments. Otherwise
-;; combine may fail.
-(define_insn "divmodhiqi3"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (ior:HI
- (ashift:HI
- (zero_extend:HI
- (truncate:QI
- (mod:HI (match_operand:HI 1 "register_operand" "0")
- (sign_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "qm")))))
- (const_int 8))
- (zero_extend:HI
- (truncate:QI
- (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH"
- "idiv{b}\t%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "QI")])
-
-(define_expand "udivmod<mode>4"
- [(parallel [(set (match_operand:SWIM248 0 "register_operand")
- (udiv:SWIM248
- (match_operand:SWIM248 1 "register_operand")
- (match_operand:SWIM248 2 "nonimmediate_operand")))
- (set (match_operand:SWIM248 3 "register_operand")
- (umod:SWIM248 (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Split with 8bit unsigned divide:
-;; if (dividend an divisor are in [0-255])
-;; use 8bit unsigned integer divide
-;; else
-;; use original integer divide
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
- (match_operand:SWI48 3 "nonimmediate_operand")))
- (set (match_operand:SWI48 1 "register_operand")
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_8BIT_IDIV
- && TARGET_QIMODE_MATH
- && can_create_pseudo_p ()
- && !optimize_insn_for_size_p ()"
- [(const_int 0)]
- "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (udiv:SI (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "nonimmediate_operand"))))
- (set (match_operand:SI 1 "register_operand")
- (umod:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && TARGET_USE_8BIT_IDIV
- && TARGET_QIMODE_MATH
- && can_create_pseudo_p ()
- && !optimize_insn_for_size_p ()"
- [(const_int 0)]
- "ix86_split_idivmod (SImode, operands, false); DONE;")
-
-(define_split
- [(set (match_operand:DI 1 "register_operand")
- (zero_extend:DI
- (umod:SI (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "nonimmediate_operand"))))
- (set (match_operand:SI 0 "register_operand")
- (udiv:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && TARGET_USE_8BIT_IDIV
- && TARGET_QIMODE_MATH
- && can_create_pseudo_p ()
- && !optimize_insn_for_size_p ()"
- [(const_int 0)]
- "ix86_split_idivmod (SImode, operands, false); DONE;")
-
-(define_insn_and_split "udivmod<mode>4_1"
- [(set (match_operand:SWI48 0 "register_operand" "=a")
- (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
- (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWI48 1 "register_operand" "=&d")
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (udiv:SWI48 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "udivmodsi4_zext_1"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (zero_extend:DI
- (udiv:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 1 "register_operand" "=&d")
- (umod:SI (match_dup 2) (match_dup 3)))
- (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
- (set (match_dup 1)
- (umod:SI (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "udivmodsi4_zext_2"
- [(set (match_operand:DI 1 "register_operand" "=&d")
- (zero_extend:DI
- (umod:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 0 "register_operand" "=a")
- (udiv:SI (match_dup 2) (match_dup 3)))
- (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "#"
- "reload_completed"
- [(set (match_dup 4) (const_int 0))
- (parallel [(set (match_dup 1)
- (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
- (set (match_dup 0)
- (udiv:SI (match_dup 2) (match_dup 3)))
- (use (match_dup 4))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[4] = gen_lowpart (SImode, operands[1]);"
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*udivmod<mode>4"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=&d")
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (udiv:SWIM248 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*udivmodsi4_zext_1"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (zero_extend:DI
- (udiv:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 1 "register_operand" "=&d")
- (umod:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
- (set (match_dup 1)
- (umod:SI (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*udivmodsi4_zext_2"
- [(set (match_operand:DI 1 "register_operand" "=&d")
- (zero_extend:DI
- (umod:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 0 "register_operand" "=a")
- (udiv:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "#"
- "reload_completed"
- [(set (match_dup 4) (const_int 0))
- (parallel [(set (match_dup 1)
- (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
- (set (match_dup 0)
- (udiv:SI (match_dup 2) (match_dup 3)))
- (use (match_dup 4))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[4] = gen_lowpart (SImode, operands[1]);"
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-;; Optimize division or modulo by constant power of 2, if the constant
-;; materializes only after expansion.
-(define_insn_and_split "*udivmod<mode>4_pow2"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
- (match_operand:SWI48 3 "const_int_operand" "n")))
- (set (match_operand:SWI48 1 "register_operand" "=r")
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
- && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
- "#"
- "&& 1"
- [(set (match_dup 1) (match_dup 2))
- (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- int v = exact_log2 (UINTVAL (operands[3]));
- operands[4] = GEN_INT (v);
- operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*udivmodsi4_pow2_zext_1"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (udiv:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "const_int_operand" "n"))))
- (set (match_operand:SI 1 "register_operand" "=r")
- (umod:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
- && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
- "#"
- "&& 1"
- [(set (match_dup 1) (match_dup 2))
- (parallel [(set (match_dup 0)
- (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- int v = exact_log2 (UINTVAL (operands[3]));
- operands[4] = GEN_INT (v);
- operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*udivmodsi4_pow2_zext_2"
- [(set (match_operand:DI 1 "register_operand" "=r")
- (zero_extend:DI
- (umod:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "const_int_operand" "n"))))
- (set (match_operand:SI 0 "register_operand" "=r")
- (umod:SI (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
- && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
- "#"
- "&& 1"
- [(set (match_dup 1) (match_dup 2))
- (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 1)
- (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
- (clobber (reg:CC FLAGS_REG))])]
-{
- int v = exact_log2 (UINTVAL (operands[3]));
- operands[4] = GEN_INT (v);
- operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")])
-
-(define_insn "*udivmod<mode>4_noext"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=d")
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_operand:SWIM248 4 "register_operand" "1"))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "div{<imodesuffix>}\t%3"
- [(set_attr "type" "idiv")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*udivmodsi4_noext_zext_1"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (zero_extend:DI
- (udiv:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 1 "register_operand" "=d")
- (umod:SI (match_dup 2) (match_dup 3)))
- (use (match_operand:SI 4 "register_operand" "1"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "div{l}\t%3"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
-
-(define_insn "*udivmodsi4_noext_zext_2"
- [(set (match_operand:DI 1 "register_operand" "=d")
- (zero_extend:DI
- (umod:SI (match_operand:SI 2 "register_operand" "0")
- (match_operand:SI 3 "nonimmediate_operand" "rm"))))
- (set (match_operand:SI 0 "register_operand" "=a")
- (udiv:SI (match_dup 2) (match_dup 3)))
- (use (match_operand:SI 4 "register_operand" "1"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "div{l}\t%3"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
-
(define_expand "udivmodqi4"
[(parallel [(set (match_operand:QI 0 "register_operand")
(udiv:QI
@@ -8176,7 +8054,7 @@
{
rtx div, mod;
rtx tmp0, tmp1;
-
+
tmp0 = gen_reg_rtx (HImode);
tmp1 = gen_reg_rtx (HImode);
@@ -8201,22 +8079,28 @@
DONE;
})
-(define_insn "udivmodhiqi3"
+;; Divide AX by r/m8, with result stored in
+;; AL <- Quotient
+;; AH <- Remainder
+;; Change div/mod to HImode and extend the second argument to HImode
+;; so that mode of div/mod matches with mode of arguments. Otherwise
+;; combine may fail.
+(define_insn "<u>divmodhiqi3"
[(set (match_operand:HI 0 "register_operand" "=a")
(ior:HI
(ashift:HI
(zero_extend:HI
(truncate:QI
(mod:HI (match_operand:HI 1 "register_operand" "0")
- (zero_extend:HI
+ (any_extend:HI
(match_operand:QI 2 "nonimmediate_operand" "qm")))))
(const_int 8))
(zero_extend:HI
(truncate:QI
- (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
+ (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_QIMODE_MATH"
- "div{b}\t%2"
+ "<sgnprefix>div{b}\t%2"
[(set_attr "type" "idiv")
(set_attr "mode" "QI")])
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, i386]: Macroize DIVMOD patterns
2019-05-14 16:22 [PATCH, i386]: Macroize DIVMOD patterns Uros Bizjak
@ 2019-05-15 12:16 ` Richard Biener
2019-05-15 12:20 ` Jakub Jelinek
2019-05-15 12:29 ` Uros Bizjak
0 siblings, 2 replies; 5+ messages in thread
From: Richard Biener @ 2019-05-15 12:16 UTC (permalink / raw)
To: Uros Bizjak; +Cc: gcc-patches
On Tue, May 14, 2019 at 6:23 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> Recent work by Richard Sandiford [1] enabled the possibility to
> macroize DIVMOD patterns in i386.md.
>
> 2019-05-14 Uroš Bizjak <ubizjak@gmail.com>
>
> * config/i386/i386.md (any_div): New code iterator.
> (paired_mod): New code attribute.
> (sgnprefix): Handle DIV and UDIV RTXes.
> (u): Ditto.
> (<u>divmod<mode>4): Macroize expander from divmod<mode>4
> and udivmod<mode>4 patterns using any_div code iterator.
> (divmod splitters): Macroize splitters using any_div code iterator.
> (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition.
> (*udivmodsi4_pow2_zext_2): Ditto.
> (*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
> and *udivmod<mode>4_noext patterns using any_div code iterator.
> (*<u>divmod<mode>4_noext_zext_1): Macroize insn from
> *divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
> patterns using any_div code iterator.
> (*<u>divmod<mode>4_noext_zext_2): Macroize insn from
> *divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
> patterns using any_div code iterator.
> (<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
> udivmodhiqi3 patterns using any_extend code iterator.
>
> The patch also reorders DIVMOD patterns a bit.
>
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
>
> Committed to mainline SVN.
I see
FAIL: gcc.target/i386/udivmod-1.c execution test
on x86_64.
> [1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html
>
> Uros.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, i386]: Macroize DIVMOD patterns
2019-05-15 12:16 ` Richard Biener
@ 2019-05-15 12:20 ` Jakub Jelinek
2019-05-15 12:29 ` Uros Bizjak
1 sibling, 0 replies; 5+ messages in thread
From: Jakub Jelinek @ 2019-05-15 12:20 UTC (permalink / raw)
To: Richard Biener; +Cc: Uros Bizjak, gcc-patches
On Wed, May 15, 2019 at 02:15:43PM +0200, Richard Biener wrote:
> I see
>
> FAIL: gcc.target/i386/udivmod-1.c execution test
>
> on x86_64.
And on i686-linux too.
Jakub
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, i386]: Macroize DIVMOD patterns
2019-05-15 12:16 ` Richard Biener
2019-05-15 12:20 ` Jakub Jelinek
@ 2019-05-15 12:29 ` Uros Bizjak
2019-05-15 18:04 ` Uros Bizjak
1 sibling, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2019-05-15 12:29 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]
I somehow missed this testsuite failure...
Attached patch is needed. I'll commit it later today.
Uros.
On Wed, May 15, 2019 at 2:16 PM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Tue, May 14, 2019 at 6:23 PM Uros Bizjak <ubizjak@gmail.com> wrote:
> >
> > Recent work by Richard Sandiford [1] enabled the possibility to
> > macroize DIVMOD patterns in i386.md.
> >
> > 2019-05-14 Uroš Bizjak <ubizjak@gmail.com>
> >
> > * config/i386/i386.md (any_div): New code iterator.
> > (paired_mod): New code attribute.
> > (sgnprefix): Handle DIV and UDIV RTXes.
> > (u): Ditto.
> > (<u>divmod<mode>4): Macroize expander from divmod<mode>4
> > and udivmod<mode>4 patterns using any_div code iterator.
> > (divmod splitters): Macroize splitters using any_div code iterator.
> > (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition.
> > (*udivmodsi4_pow2_zext_2): Ditto.
> > (*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
> > and *udivmod<mode>4_noext patterns using any_div code iterator.
> > (*<u>divmod<mode>4_noext_zext_1): Macroize insn from
> > *divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
> > patterns using any_div code iterator.
> > (*<u>divmod<mode>4_noext_zext_2): Macroize insn from
> > *divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
> > patterns using any_div code iterator.
> > (<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
> > udivmodhiqi3 patterns using any_extend code iterator.
> >
> > The patch also reorders DIVMOD patterns a bit.
> >
> > Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> >
> > Committed to mainline SVN.
>
> I see
>
> FAIL: gcc.target/i386/udivmod-1.c execution test
>
> on x86_64.
>
> > [1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html
> >
> > Uros.
[-- Attachment #2: p.diff.txt --]
[-- Type: text/plain, Size: 3779 bytes --]
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index a55d4923be48..36b27898833e 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -984,7 +984,7 @@ predict_jump (int prob)
void
ix86_split_idivmod (machine_mode mode, rtx operands[],
- bool signed_p)
+ bool unsigned_p)
{
rtx_code_label *end_label, *qimode_label;
rtx div, mod;
@@ -1000,22 +1000,22 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
if (GET_MODE (operands[0]) == SImode)
{
if (GET_MODE (operands[1]) == SImode)
- gen_divmod4_1 = signed_p ? gen_divmodsi4_1 : gen_udivmodsi4_1;
+ gen_divmod4_1 = unsigned_p ? gen_udivmodsi4_1 : gen_divmodsi4_1;
else
gen_divmod4_1
- = signed_p ? gen_divmodsi4_zext_2 : gen_udivmodsi4_zext_2;
+ = unsigned_p ? gen_udivmodsi4_zext_2 : gen_divmodsi4_zext_2;
gen_zero_extend = gen_zero_extendqisi2;
}
else
{
gen_divmod4_1
- = signed_p ? gen_divmodsi4_zext_1 : gen_udivmodsi4_zext_1;
+ = unsigned_p ? gen_udivmodsi4_zext_1 : gen_divmodsi4_zext_1;
gen_zero_extend = gen_zero_extendqidi2;
}
gen_test_ccno_1 = gen_testsi_ccno_1;
break;
case E_DImode:
- gen_divmod4_1 = signed_p ? gen_divmoddi4_1 : gen_udivmoddi4_1;
+ gen_divmod4_1 = unsigned_p ? gen_udivmoddi4_1 : gen_divmoddi4_1;
gen_test_ccno_1 = gen_testdi_ccno_1;
gen_zero_extend = gen_zero_extendqidi2;
break;
@@ -1061,15 +1061,15 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
tmp2 = lowpart_subreg (QImode, operands[3], mode);
emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, tmp2));
- if (signed_p)
+ if (unsigned_p)
{
- div = gen_rtx_DIV (mode, operands[2], operands[3]);
- mod = gen_rtx_MOD (mode, operands[2], operands[3]);
+ div = gen_rtx_UDIV (mode, operands[2], operands[3]);
+ mod = gen_rtx_UMOD (mode, operands[2], operands[3]);
}
else
{
- div = gen_rtx_UDIV (mode, operands[2], operands[3]);
- mod = gen_rtx_UMOD (mode, operands[2], operands[3]);
+ div = gen_rtx_DIV (mode, operands[2], operands[3]);
+ mod = gen_rtx_MOD (mode, operands[2], operands[3]);
}
if (mode == SImode)
{
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 05411221197f..b6e44c82d217 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -939,7 +939,8 @@
(define_code_attr s [(sign_extend "s") (zero_extend "u")])
(define_code_attr u [(sign_extend "") (zero_extend "u")
(div "") (udiv "u")])
-(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
+(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
+ (div "false") (udiv "true")])
;; Used in signed and unsigned truncations.
(define_code_iterator any_truncate [ss_truncate truncate us_truncate])
@@ -7505,7 +7506,7 @@
&& can_create_pseudo_p ()
&& !optimize_insn_for_size_p ()"
[(const_int 0)]
- "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
+ "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
(define_split
[(set (match_operand:DI 0 "register_operand")
@@ -7521,7 +7522,7 @@
&& can_create_pseudo_p ()
&& !optimize_insn_for_size_p ()"
[(const_int 0)]
- "ix86_split_idivmod (SImode, operands, true); DONE;")
+ "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
(define_split
[(set (match_operand:DI 1 "register_operand")
@@ -7537,7 +7538,7 @@
&& can_create_pseudo_p ()
&& !optimize_insn_for_size_p ()"
[(const_int 0)]
- "ix86_split_idivmod (SImode, operands, true); DONE;")
+ "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
(define_insn_and_split "divmod<mode>4_1"
[(set (match_operand:SWI48 0 "register_operand" "=a")
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, i386]: Macroize DIVMOD patterns
2019-05-15 12:29 ` Uros Bizjak
@ 2019-05-15 18:04 ` Uros Bizjak
0 siblings, 0 replies; 5+ messages in thread
From: Uros Bizjak @ 2019-05-15 18:04 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
On Wed, May 15, 2019 at 2:29 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> I somehow missed this testsuite failure...
>
> Attached patch is needed. I'll commit it later today.
Now regtested on x86_64-linux-gnu {,-m32} and committed with the
following ChangeLog:
2019-05-15 Uroš Bizjak <ubizjak@gmail.com>
* config/i386/i386-expand.c (ix86_split_idivmod): Rename
signed_p argument to unsigned_p. Update all uses for changed polarity.
* config/i386/i386.md (u_bool): Handle DIV and UDIV RTXes.
(divmod splitters): Use u_bool macro in the call to ix86_split_idivmod.
Uros.
> On Wed, May 15, 2019 at 2:16 PM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Tue, May 14, 2019 at 6:23 PM Uros Bizjak <ubizjak@gmail.com> wrote:
> > >
> > > Recent work by Richard Sandiford [1] enabled the possibility to
> > > macroize DIVMOD patterns in i386.md.
> > >
> > > 2019-05-14 Uroš Bizjak <ubizjak@gmail.com>
> > >
> > > * config/i386/i386.md (any_div): New code iterator.
> > > (paired_mod): New code attribute.
> > > (sgnprefix): Handle DIV and UDIV RTXes.
> > > (u): Ditto.
> > > (<u>divmod<mode>4): Macroize expander from divmod<mode>4
> > > and udivmod<mode>4 patterns using any_div code iterator.
> > > (divmod splitters): Macroize splitters using any_div code iterator.
> > > (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition.
> > > (*udivmodsi4_pow2_zext_2): Ditto.
> > > (*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
> > > and *udivmod<mode>4_noext patterns using any_div code iterator.
> > > (*<u>divmod<mode>4_noext_zext_1): Macroize insn from
> > > *divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
> > > patterns using any_div code iterator.
> > > (*<u>divmod<mode>4_noext_zext_2): Macroize insn from
> > > *divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
> > > patterns using any_div code iterator.
> > > (<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
> > > udivmodhiqi3 patterns using any_extend code iterator.
> > >
> > > The patch also reorders DIVMOD patterns a bit.
> > >
> > > Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> > >
> > > Committed to mainline SVN.
> >
> > I see
> >
> > FAIL: gcc.target/i386/udivmod-1.c execution test
> >
> > on x86_64.
> >
> > > [1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html
> > >
> > > Uros.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-05-15 18:04 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-14 16:22 [PATCH, i386]: Macroize DIVMOD patterns Uros Bizjak
2019-05-15 12:16 ` Richard Biener
2019-05-15 12:20 ` Jakub Jelinek
2019-05-15 12:29 ` Uros Bizjak
2019-05-15 18:04 ` Uros Bizjak
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).