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