[gcc(refs/users/meissner/heads/work252-dmf)] Add saturate subtract support

Michael Meissner via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:76a719daa8ab6eb861d8021168201c3f7022705f

commit 76a719daa8ab6eb861d8021168201c3f7022705f
Author: Michael Meissner <[email protected]>
Date:   Fri Jul 24 00:19:18 2026 -0400

    Add saturate subtract support
    
    This patch adds support for saturating subtract instructions that might be added
    to a future PowerPC.r  I think I had originally submitted patches that added a
    new built-in function to generate the subfus and subdus instructions.  Segher
    suggested that instead of generating a built-in function, that I should just
    having GCC automatically recognize cases where a saturating subtract could be
    generated.  This patch generates the saturating subtract instructions in the
    appropriate context.
    
    I have committed all of the patches in my backlog (dense math registers, other
    -mcpu=future instructions, random bug fixes, support for _Float16 and
    __bfloat16, and optimizations for vector logical operations on power10/power11)
    into the IBM vendor branch:
    
            vendors/ibm/gcc-17-future
    
    2026-07-24   Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/rs6000.md (gtu_geu): New code iterator.
            (subfus<mode>3_<code>): New insns.
    
    gcc/testsuite/
    
            * gcc.target/powerpc/saturate-subtract-1.c: New test.
            * gcc.target/powerpc/saturate-subtract-2.c: Likewise.
            * lib/target-supports.exp (check_effective_target_powerpc_future_ok):
            New target test.

Diff:
---
 gcc/config/rs6000/rs6000.md                        | 14 ++++++++
 .../gcc.target/powerpc/saturate-subtract-1.c       | 39 +++++++++++++++++++++
 .../gcc.target/powerpc/saturate-subtract-2.c       | 40 ++++++++++++++++++++++
 gcc/testsuite/lib/target-supports.exp              | 13 +++++++
 4 files changed, 106 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e06dcec65889..ce2714447a2e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2409,6 +2409,20 @@
   ""
 )
 
+;; Saturating subtract
+(define_code_iterator gtu_geu [gtu geu])
+
+(define_insn "*subfus<mode>3_<code>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(if_then_else:GPR (gtu_geu (match_operand:GPR 1 "gpc_reg_operand" "r")
+				   (match_operand:GPR 2 "gpc_reg_operand" "r"))
+			  (minus:GPR (match_dup 1)
+				     (match_dup 2))
+			  (const_int 0)))]
+  "TARGET_FUTURE"
+  "sub<wd>us %0,%1,%2"
+  [(set_attr "type" "add")])
+
 (define_insn "@neg<mode>2"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
 	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
diff --git a/gcc/testsuite/gcc.target/powerpc/saturate-subtract-1.c b/gcc/testsuite/gcc.target/powerpc/saturate-subtract-1.c
new file mode 100644
index 000000000000..c32a70a5e898
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/saturate-subtract-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+/* { dg-require-effective-target powerpc_future_ok } */
+
+/* Check that saturating subtract (subfus) is generated.  Check that all
+   combinations of >, >=, <, and <= are optimized.  */
+
+#ifndef TYPE
+#define TYPE	unsigned int
+#endif
+
+void
+saturated_subtract_gt (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a > b) ? a - b : 0;
+}
+
+void
+saturated_subtract_ge (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a >= b) ? a - b : 0;
+}
+
+void
+saturated_subtract_lt (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a < b) ? 0 : a - b;
+}
+
+void
+saturated_subtract_le (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a <= b) ? 0 : a - b;
+}
+
+/* { dg-final { scan-assembler-times {\msubwus\M} 4 } } */
+/* { dg-final { scan-assembler-not   {\mcmplw\M}    } } */
+/* { dg-final { scan-assembler-not   {\misel\M}     } } */
+/* { dg-final { scan-assembler-not   {\msubf\M}     } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/saturate-subtract-2.c b/gcc/testsuite/gcc.target/powerpc/saturate-subtract-2.c
new file mode 100644
index 000000000000..482d7384c172
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/saturate-subtract-2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+/* Check that saturating subtract (subfus) is generated.  Check that all
+   combinations of >, >=, <, and <= are optimized.  */
+
+#ifndef TYPE
+#define TYPE	unsigned long long
+#endif
+
+void
+saturated_subtract_gt (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a > b) ? a - b : 0;
+}
+
+void
+saturated_subtract_ge (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a >= b) ? a - b : 0;
+}
+
+void
+saturated_subtract_lt (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a < b) ? 0 : a - b;
+}
+
+void
+saturated_subtract_le (TYPE a, TYPE b, TYPE *p)
+{
+  *p = (a <= b) ? 0 : a - b;
+}
+
+/* { dg-final { scan-assembler-times {\msubdus\M} 4 } } */
+/* { dg-final { scan-assembler-not   {\mcmpld\M}    } } */
+/* { dg-final { scan-assembler-not   {\misel\M}     } } */
+/* { dg-final { scan-assembler-not   {\msubf\M}     } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 57a6df4f83ba..4f3c6cabf345 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8337,6 +8337,19 @@ proc check_htm_hw_available { } {
 	}
     }]
 }
+
+# Return 1 if this is a PowerPC target supporting -mcpu=future
+
+proc check_effective_target_powerpc_future_ok { } {
+    return [check_no_compiler_messages powerpc_future_ok object {
+	unsigned long a, b, c;
+	int main (void) {
+	    asm ("subdus %0,%1,%2" : "=r" (a) : "r" (b), "r" (c));
+	    return 0;
+	}
+    } "-mcpu=future"]
+}
+
 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
 
 proc check_effective_target_powerpc_ppu_ok { } {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.