The assertion in the preparation statements of the split
*branch<X:mode>_mask_twobits_equals_singlebit can be false under rare
circumstances.  Moving the conditional to the insn condition seems
reasonable.

gcc/ChangeLog:

        * config/riscv/bitmanip.md: Move assertion expression to insn
condition

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zbs-if_then_else-02.c: New test.
---
 gcc/config/riscv/bitmanip.md                  |  5 +--
 .../gcc.target/riscv/zbs-if_then_else-02.c    | 32 +++++++++++++++++++
 2 files changed, 33 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-02.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 166ddd9db9e6..b71857166d6b 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1131,7 +1131,7 @@ (define_insn_and_split 
"*branch<X:mode>_mask_twobits_equals_singlebit"
         (pc)))
    (clobber (match_scratch:X 5 "=&r"))
    (clobber (match_scratch:X 6 "=&r"))]
-  "TARGET_ZBS && TARGET_ZBB"
+  "TARGET_ZBS && TARGET_ZBB && (UINTVAL (operands[3]) & UINTVAL (operands[4]))"
   "#"
   "&& reload_completed"
   [(set (match_dup 5) (zero_extract:X (match_dup 2)
@@ -1148,9 +1148,6 @@ (define_insn_and_split 
"*branch<X:mode>_mask_twobits_equals_singlebit"
    unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
    unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
 
-   /* We should never see an unsatisfiable condition.  */
-   gcc_assert (twobits_mask & singlebit_mask);
-
    int setbit = ctz_hwi (singlebit_mask);
    int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
 
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-02.c 
b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-02.c
new file mode 100644
index 000000000000..3393bea88981
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-02.c
@@ -0,0 +1,32 @@
+/* { dg-do link  { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64d -flto" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+
+struct S {
+  int a;
+  char b;
+  int c;
+} s;
+
+const signed char c = -37;
+int d;
+struct S v1[] = {{0, 8}, 0, 0, -108976}, v2[] = {{}, 0, 0, 2804};
+int a;
+struct S v3[3];
+int *p = &a;
+
+void foo() {
+  int a;
+  if (a)
+    ;
+  else if (v1[0].b)
+    s.a = 0;
+  else
+    d = 0;
+  if (*p)
+    if (v3[1].c)
+      if (1 ^ (d & c & v2[1].c & ~v1[1].c | s.a))
+        v3[2].c = 0;
+}
+
+int main() { foo(); }
-- 
2.46.0

Reply via email to