simplify_gen_binary (XOR, mode, op1,
XEXP (op0, 1)));
+ /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
+ 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
+ if (CONST_SCALAR_INT_P (op1)
+ && GET_CODE (op0) == XOR
+ && CONST_SCALAR_INT_P (XEXP (op0, 1))
+ && nonzero_bits (XEXP (op0, 0), mode) == 1
+ && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
+ && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
+ return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
+ simplify_gen_binary (XOR, mode, op1,
+ XEXP (op0, 1)));
+
/* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
&& GET_CODE (op0) == MULT
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+#include <stdint.h>
+
+#define COMPARISON(TYPE, OP, OPN, RESULT_TRUE, RESULT_FALSE) \
+ TYPE test_##OPN(TYPE x, TYPE y) { \
+ return (x OP y) ? RESULT_TRUE : RESULT_FALSE; \
+ }
+
+/* Signed comparisons */
+COMPARISON(int64_t, >, GT1, 2, 3)
+COMPARISON(int64_t, >, GT2, 5, 6)
+
+COMPARISON(int64_t, <, LT1, 2, 3)
+COMPARISON(int64_t, <, LT2, 5, 6)
+
+COMPARISON(int64_t, >=, GE1, 3, 2)
+COMPARISON(int64_t, >=, GE2, 6, 5)
+
+COMPARISON(int64_t, <=, LE1, 3, 2)
+COMPARISON(int64_t, <=, LE2, 6, 5)
+
+/* Unsigned comparisons */
+COMPARISON(uint64_t, >, GTU1, 2, 3)
+COMPARISON(uint64_t, >, GTU2, 5, 6)
+
+COMPARISON(uint64_t, <, LTU1, 2, 3)
+COMPARISON(uint64_t, <, LTU2, 5, 6)
+
+COMPARISON(uint64_t, >=, GEU1, 3, 2)
+COMPARISON(uint64_t, >=, GEU2, 6, 5)
+
+COMPARISON(uint64_t, <=, LEU1, 3, 2)
+COMPARISON(uint64_t, <=, LEU2, 6, 5)
+
+#define COMPARISON_IMM(TYPE, OP, OPN, RESULT_TRUE, RESULT_FALSE) \
+ TYPE testIMM_##OPN(TYPE x) { \
+ return (x OP -3) ? RESULT_TRUE : RESULT_FALSE; \
+ }
+
+/* Signed comparisons with immediate */
+COMPARISON_IMM(int64_t, >, GT1, 3, 2)
+
+COMPARISON_IMM(int64_t, <, LT1, 2, 3)
+
+COMPARISON_IMM(int64_t, >=, GE1, 3, 2)
+
+COMPARISON_IMM(int64_t, <=, LE1, 2, 3)
+
+/* { dg-final { scan-assembler-times "sgt\\t" 4 } } */
+/* { dg-final { scan-assembler-times "sgtu\\t" 4 } } */
+/* { dg-final { scan-assembler-times "slt\\t" 4 } } */
+/* { dg-final { scan-assembler-times "sltu\\t" 4 } } */
+/* { dg-final { scan-assembler-times "slti\\t" 4 } } */
+/* { dg-final { scan-assembler-times "xori\\ta0,a0,1" 8 } } */
+/* { dg-final { scan-assembler-times "xori\\ta0,a0,3" 12 } } */
+