public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: HAO CHEN GUI <guihaoc@linux.ibm.com>
To: gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Segher Boessenkool <segher@kernel.crashing.org>,
	David <dje.gcc@gmail.com>, "Kewen.Lin" <linkw@linux.ibm.com>,
	Peter Bergner <bergner@linux.ibm.com>
Subject: [PATCH, rs6000] Use CC for BCD operations [PR100736]
Date: Thu, 16 Jun 2022 14:36:53 +0800	[thread overview]
Message-ID: <887ce9bb-3a34-b880-41b1-4ac2cfb743eb@linux.ibm.com> (raw)

Hi,
  This patch uses CC instead of CCFP for all BCD operations. Thus, infinite
math flag has no impact on BCD operations. To support BCD overflow and
invalid coding, ordered and unordered are added into CC mode. With CC,
"ge" and "le" are converted to reverse comparison. So the invalid coding
needs to be tested separately.

  This patch also replaces bcdadd with bcdsub for BCD invaliding coding
expand. The bcdsub with two identical numbers doesn't cause overflow while
bcdadd could.

  Another patch which creates a dedicated CC mode for BCD operations is
ready. With this patch, we don't need ordered and unordered in CC. Please
advice if I can submit it.

  Bootstrapped and tested on powerpc64-linux BE and LE with no regressions.
Is this okay for trunk? Any recommendations? Thanks a lot.

2022-06-16 Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	PR target/100736
	* config/rs6000/altivec.md (bcd<bcd_add_sub>_<mode>): Replace CCFP with
	CC
	(*bcd<bcd_add_sub>_test_<mode>): Replace CCFP with CC.  Generate
	condition insn with CC mode.
	(*bcdinvalid_<mode>): Replace CCFP with CC.  Replace bcdadd. with
	bcdsub.
	(bcdinvalid_<mode>): Replace CCFP with CC.
	(bcdshift_v16qi): Likewise.
	(bcdmul10_v16qi): Likewise.
	(bcddiv10_v16qi): Likewise.
	(peephole for bcd_add/sub): Likewise.
	* config/rs6000/predicates.md (branch_comparison_operator): Add
	ordered and unordered in CC mode.
	* config/rs6000/rs6000.cc (validate_condition_mode): Likewise.

gcc/testsuite/
	PR target/100736
	* gcc.target/powerpc/bcd-4.c: Adjust number of bcdadd and bcdsub.
	Scan no cror insns.

patch.diff
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index efc8ae35c2e..5ffbab17a9e 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -4379,7 +4379,7 @@ (define_insn "bcd<bcd_add_sub>_<mode>"
 		      (match_operand:VBCD 2 "register_operand" "v")
 		      (match_operand:QI 3 "const_0_to_1_operand" "n")]
 		     UNSPEC_BCD_ADD_SUB))
-   (clobber (reg:CCFP CR6_REGNO))]
+   (clobber (reg:CC CR6_REGNO))]
   "TARGET_P8_VECTOR"
   "bcd<bcd_add_sub>. %0,%1,%2,%3"
   [(set_attr "type" "vecsimple")])
@@ -4389,9 +4389,9 @@ (define_insn "bcd<bcd_add_sub>_<mode>"
 ;; UNORDERED test on an integer type (like V1TImode) is not defined.  The type
 ;; probably should be one that can go in the VMX (Altivec) registers, so we
 ;; can't use DDmode or DFmode.
-(define_insn "*bcd<bcd_add_sub>_test_<mode>"
-  [(set (reg:CCFP CR6_REGNO)
-	(compare:CCFP
+(define_insn "bcd<bcd_add_sub>_test_<mode>"
+  [(set (reg:CC CR6_REGNO)
+	(compare:CC
 	 (unspec:V2DF [(match_operand:VBCD 1 "register_operand" "v")
 		       (match_operand:VBCD 2 "register_operand" "v")
 		       (match_operand:QI 3 "const_0_to_1_operand" "i")]
@@ -4408,8 +4408,8 @@ (define_insn "*bcd<bcd_add_sub>_test2_<mode>"
 		      (match_operand:VBCD 2 "register_operand" "v")
 		      (match_operand:QI 3 "const_0_to_1_operand" "i")]
 		     UNSPEC_BCD_ADD_SUB))
-   (set (reg:CCFP CR6_REGNO)
-	(compare:CCFP
+   (set (reg:CC CR6_REGNO)
+	(compare:CC
 	 (unspec:V2DF [(match_dup 1)
 		       (match_dup 2)
 		       (match_dup 3)]
@@ -4502,8 +4502,8 @@ (define_insn "vclrrb"
    [(set_attr "type" "vecsimple")])

 (define_expand "bcd<bcd_add_sub>_<code>_<mode>"
-  [(parallel [(set (reg:CCFP CR6_REGNO)
-		   (compare:CCFP
+  [(parallel [(set (reg:CC CR6_REGNO)
+		   (compare:CC
 		    (unspec:V2DF [(match_operand:VBCD 1 "register_operand")
 				  (match_operand:VBCD 2 "register_operand")
 				  (match_operand:QI 3 "const_0_to_1_operand")]
@@ -4511,33 +4511,56 @@ (define_expand "bcd<bcd_add_sub>_<code>_<mode>"
 		    (match_dup 4)))
 	      (clobber (match_scratch:VBCD 5))])
    (set (match_operand:SI 0 "register_operand")
-	(BCD_TEST:SI (reg:CCFP CR6_REGNO)
+	(BCD_TEST:SI (reg:CC CR6_REGNO)
 		     (const_int 0)))]
   "TARGET_P8_VECTOR"
 {
   operands[4] = CONST0_RTX (V2DFmode);
+  emit_insn (gen_bcd<bcd_add_sub>_test_<mode> (operands[0], operands[1],
+					       operands[2], operands[3],
+					       operands[4]));
+
+  rtx cr6 = gen_rtx_REG (CCmode, CR6_REGNO);
+  rtx condition_rtx = gen_rtx_<CODE> (SImode, cr6, const0_rtx);
+  rtx_code cond_code = GET_CODE (condition_rtx);
+
+  if (cond_code == GE || cond_code == LE)
+    {
+      rtx not_result = gen_reg_rtx (CCEQmode);
+      rtx not_op, rev_cond_rtx;
+      rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (SImode,
+							       cond_code),
+				     SImode, XEXP (condition_rtx, 0),
+				     const0_rtx);
+      not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
+      emit_insn (gen_rtx_SET (not_result, not_op));
+      condition_rtx = gen_rtx_EQ (SImode, not_result, const0_rtx);
+    }
+
+  emit_insn (gen_rtx_SET (operands[0], condition_rtx));
+  DONE;
 })

 (define_insn "*bcdinvalid_<mode>"
-  [(set (reg:CCFP CR6_REGNO)
-	(compare:CCFP
+  [(set (reg:CC CR6_REGNO)
+	(compare:CC
 	 (unspec:V2DF [(match_operand:VBCD 1 "register_operand" "v")]
 		      UNSPEC_BCDADD)
 	 (match_operand:V2DF 2 "zero_constant" "j")))
    (clobber (match_scratch:VBCD 0 "=v"))]
   "TARGET_P8_VECTOR"
-  "bcdadd. %0,%1,%1,0"
+  "bcdsub. %0,%1,%1,0"
   [(set_attr "type" "vecsimple")])

 (define_expand "bcdinvalid_<mode>"
-  [(parallel [(set (reg:CCFP CR6_REGNO)
-		   (compare:CCFP
+  [(parallel [(set (reg:CC CR6_REGNO)
+		   (compare:CC
 		    (unspec:V2DF [(match_operand:VBCD 1 "register_operand")]
 				 UNSPEC_BCDADD)
 		    (match_dup 2)))
 	      (clobber (match_scratch:VBCD 3))])
    (set (match_operand:SI 0 "register_operand")
-	(unordered:SI (reg:CCFP CR6_REGNO)
+	(unordered:SI (reg:CC CR6_REGNO)
 		      (const_int 0)))]
   "TARGET_P8_VECTOR"
 {
@@ -4550,7 +4573,7 @@ (define_insn "bcdshift_v16qi"
 		       (match_operand:V16QI 2 "register_operand" "v")
 		       (match_operand:QI 3 "const_0_to_1_operand" "n")]
 		     UNSPEC_BCDSHIFT))
-   (clobber (reg:CCFP CR6_REGNO))]
+   (clobber (reg:CC CR6_REGNO))]
   "TARGET_P8_VECTOR"
   "bcds. %0,%1,%2,%3"
   [(set_attr "type" "vecsimple")])
@@ -4559,7 +4582,7 @@ (define_expand "bcdmul10_v16qi"
   [(set (match_operand:V16QI 0 "register_operand")
 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand")]
 		      UNSPEC_BCDSHIFT))
-   (clobber (reg:CCFP CR6_REGNO))]
+   (clobber (reg:CC CR6_REGNO))]
   "TARGET_P9_VECTOR"
 {
   rtx one = gen_reg_rtx (V16QImode);
@@ -4574,7 +4597,7 @@ (define_expand "bcddiv10_v16qi"
   [(set (match_operand:V16QI 0 "register_operand")
 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand")]
 		      UNSPEC_BCDSHIFT))
-   (clobber (reg:CCFP CR6_REGNO))]
+   (clobber (reg:CC CR6_REGNO))]
   "TARGET_P9_VECTOR"
 {
   rtx one = gen_reg_rtx (V16QImode);
@@ -4598,9 +4621,9 @@ (define_peephole2
 				 (match_operand:V1TI 2 "register_operand")
 				 (match_operand:QI 3 "const_0_to_1_operand")]
 				UNSPEC_BCD_ADD_SUB))
-	      (clobber (reg:CCFP CR6_REGNO))])
-   (parallel [(set (reg:CCFP CR6_REGNO)
-		   (compare:CCFP
+	      (clobber (reg:CC CR6_REGNO))])
+   (parallel [(set (reg:CC CR6_REGNO)
+		   (compare:CC
 		    (unspec:V2DF [(match_dup 1)
 				  (match_dup 2)
 				  (match_dup 3)]
@@ -4613,8 +4636,8 @@ (define_peephole2
 				 (match_dup 2)
 				 (match_dup 3)]
 				UNSPEC_BCD_ADD_SUB))
-	      (set (reg:CCFP CR6_REGNO)
-		   (compare:CCFP
+	      (set (reg:CC CR6_REGNO)
+		   (compare:CC
 		    (unspec:V2DF [(match_dup 1)
 				  (match_dup 2)
 				  (match_dup 3)]
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b1fcc69bb60..28567bcc64c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1316,7 +1316,7 @@ (define_predicate "branch_comparison_operator"
 	  (if_then_else (match_test "flag_finite_math_only")
 	    (match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
 	    (match_code "lt,gt,eq,unordered,unge,unle,ne,ordered"))
-	  (match_code "lt,ltu,le,leu,gt,gtu,ge,geu,eq,ne"))
+	  (match_code "lt,ltu,le,leu,gt,gtu,ge,geu,eq,ne,unordered,ordered"))
 	(match_test "validate_condition_mode (GET_CODE (op),
 					      GET_MODE (XEXP (op, 0))),
 		     1")))
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d4defc855d0..15f813d9cf5 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -11249,11 +11249,13 @@ validate_condition_mode (enum rtx_code code, machine_mode mode)
 	      || mode == CCUNSmode);

   gcc_assert (mode == CCFPmode
-	      || (code != ORDERED && code != UNORDERED
-		  && code != UNEQ && code != LTGT
+	      || (code != UNEQ && code != LTGT
 		  && code != UNGT && code != UNLT
 		  && code != UNGE && code != UNLE));

+  gcc_assert (mode == CCFPmode || mode == CCmode
+	      || (code != ORDERED && code != UNORDERED));
+
   /* These are invalid; the information is not there.  */
   gcc_assert (mode != CCEQmode || code == EQ || code == NE);
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-4.c b/gcc/testsuite/gcc.target/powerpc/bcd-4.c
index 2c8554dfe82..3c25ed60e17 100644
--- a/gcc/testsuite/gcc.target/powerpc/bcd-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bcd-4.c
@@ -2,10 +2,11 @@
 /* { dg-require-effective-target int128 } */
 /* { dg-require-effective-target power10_hw } */
 /* { dg-options "-mdejagnu-cpu=power10 -O2 -save-temps" } */
-/* { dg-final { scan-assembler-times {\mbcdadd\M} 7 } } */
-/* { dg-final { scan-assembler-times {\mbcdsub\M} 18 } } */
+/* { dg-final { scan-assembler-times {\mbcdadd\M} 5 } } */
+/* { dg-final { scan-assembler-times {\mbcdsub\M} 20 } } */
 /* { dg-final { scan-assembler-times {\mbcds\M} 2 } } */
 /* { dg-final { scan-assembler-times {\mdenbcdq\M} 1 } } */
+/* { dg-final { scan-assembler-not {\mcror\M} 1 } } */

 #include <altivec.h>



             reply	other threads:[~2022-06-16  6:37 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-16  6:36 HAO CHEN GUI [this message]
2022-06-16 11:24 ` Segher Boessenkool
2022-06-17  8:19   ` HAO CHEN GUI
2022-06-17 18:08     ` Segher Boessenkool

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=887ce9bb-3a34-b880-41b1-4ac2cfb743eb@linux.ibm.com \
    --to=guihaoc@linux.ibm.com \
    --cc=bergner@linux.ibm.com \
    --cc=dje.gcc@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=linkw@linux.ibm.com \
    --cc=segher@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).