&& (INTVAL (XEXP (op0, 1))
== ~INTVAL (XEXP (op1, 1))))
{
- /* The IOR may be on both sides. */
+ /* The IOR/XOR may be on both sides. */
rtx top0 = NULL_RTX, top1 = NULL_RTX;
- if (GET_CODE (XEXP (op1, 0)) == IOR)
+ if (GET_CODE (XEXP (op1, 0)) == IOR
+ || GET_CODE (XEXP (op1, 0)) == XOR)
top0 = op0, top1 = op1;
- else if (GET_CODE (XEXP (op0, 0)) == IOR)
+ else if (GET_CODE (XEXP (op0, 0)) == IOR
+ || GET_CODE (XEXP (op0, 0)) == XOR)
top0 = op1, top1 = op0;
if (top0 && top1)
{
- /* X may be on either side of the inner IOR. */
+ /* X may be on either side of the inner IOR/XOR. */
rtx tem = NULL_RTX;
if (rtx_equal_p (XEXP (top0, 0),
XEXP (XEXP (top1, 0), 0)))
XEXP (XEXP (top1, 0), 1)))
tem = XEXP (XEXP (top1, 0), 0);
if (tem)
- return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
+ return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
+ mode, XEXP (top0, 0),
simplify_gen_binary
(AND, mode, tem, XEXP (top1, 1)));
}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gc_zicond -mabi=lp64d" { target rv64 } } */
+/* { dg-additional-options "-march=rv32gc_zicond -mabi=ilp32" { target rv32 } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#define N 0x202
+#define OP ^
+
+unsigned f(unsigned a, unsigned b)
+{
+ unsigned t = a OP b;
+ unsigned t1 = t&N;
+ unsigned t2 = a&~N;
+ return t1 | t2;
+}
+
+/* { dg-final { scan-assembler-times "andi\t" 1 } } */
+/* { dg-final { scan-assembler-times "xor\t" 1 } } */
+/* { dg-final { scan-assembler-not "\tor\t" } } */