;; Where C1 is not a LUI operand, but ~C1 is a LUI operand
(define_insn_and_split "*lui_constraint<X:mode>_and_to_or"
- [(set (match_operand:X 0 "register_operand" "=r")
+ [(set (match_operand:X 0 "register_operand" "=r")
(plus:X (and:X (match_operand:X 1 "register_operand" "r")
(match_operand 2 "const_int_operand"))
(match_operand 3 "const_int_operand")))
<= riscv_const_insns (operands[3], false)))"
"#"
"&& reload_completed"
- [(set (match_dup 4) (match_dup 5))
- (set (match_dup 0) (ior:X (match_dup 1) (match_dup 4)))
- (set (match_dup 4) (match_dup 6))
- (set (match_dup 0) (minus:X (match_dup 0) (match_dup 4)))]
+ [(const_int 0)]
{
operands[5] = GEN_INT (~INTVAL (operands[2]));
operands[6] = GEN_INT ((~INTVAL (operands[2])) | (-INTVAL (operands[3])));
+
+ /* This is always a LUI operand, so it's safe to just emit. */
+ emit_move_insn (operands[4], operands[5]);
+
+ rtx x = gen_rtx_IOR (word_mode, operands[1], operands[4]);
+ emit_move_insn (operands[0], x);
+
+ /* This may require multiple steps to synthesize. */
+ riscv_emit_move (operands[4], operands[6]);
+ x = gen_rtx_MINUS (word_mode, operands[0], operands[4]);
+ emit_move_insn (operands[0], x);
}
[(set_attr "type" "arith")])
--- /dev/null
+/* { dg-do compile { target { rv64 } } } */
+
+extern void NG (void);
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+void f74(void) {
+ int16_t x309 = 0x7fff;
+ volatile int32_t x310 = 0x7fffffff;
+ int8_t x311 = 59;
+ int16_t x312 = -0x8000;
+ static volatile int32_t t74 = 614992577;
+
+ t74 = (x309==((x310^x311)%x312));
+
+ if (t74 != 0) { NG(); } else { ; }
+
+}
+