2929// (x == 0) ? x : y -> CZEROEQZ y x (when x is the condition)
3030(OR (CZEROEQZ <t> x (SEQZ x)) (CZERONEZ <t> y (SEQZ x))) && buildcfg.GORISCV64 >= 23 => (CZEROEQZ <t> y x)
3131
32- // (z == 0) ? (x + y) : x -> ADD x (CZERONEZ y z)
33- (OR (CZEROEQZ <t> (ADD x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23 => (ADD x (CZERONEZ <t> y z))
34- // (z != 0) ? (x + y) : x -> ADD x (CZEROEQZ y z)
35- (OR (CZEROEQZ <t> (ADD x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23 => (ADD x (CZEROEQZ <t> y z))
36-
37- // (z == 0) ? (x - y) : x -> SUB x (CZERONEZ y z)
38- (OR (CZEROEQZ <t> (SUB x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23 => (SUB x (CZERONEZ <t> y z))
39- // (z != 0) ? (x - y) : x -> SUB x (CZEROEQZ y z)
40- (OR (CZEROEQZ <t> (SUB x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23 => (SUB x (CZEROEQZ <t> y z))
41-
42- // (z == 0) ? (x | y) : x -> OR x (CZERONEZ y z)
43- (OR (CZEROEQZ <t> (OR x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23 => (OR x (CZERONEZ <t> y z))
44- // (z != 0) ? (x | y) : x -> OR x (CZEROEQZ y z)
45- (OR (CZEROEQZ <t> (OR x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23 => (OR x (CZEROEQZ <t> y z))
46-
47- // (z == 0) ? (x ^ y) : x -> XOR x (CZERONEZ y z)
48- (OR (CZEROEQZ <t> (XOR x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23 => (XOR x (CZERONEZ <t> y z))
49- // (z != 0) ? (x ^ y) : x -> XOR x (CZEROEQZ y z)
50- (OR (CZEROEQZ <t> (XOR x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23 => (XOR x (CZEROEQZ <t> y z))
51-
52- // (z == 0) ? (x & y) : x -> OR (AND x y) (CZEROEQZ x z)
53- (OR (CZEROEQZ <t> (AND x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZEROEQZ <t> x z))
54- // (z != 0) ? (x & y) : x -> OR (AND x y) (CZERONEZ x z)
55- (OR (CZEROEQZ <t> (AND x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZERONEZ <t> x z))
32+ // OR-form optimizations for arithmetic/logic ops (64-bit and 32-bit)
33+ // (z == 0) ? ((OP x y)) : x => (OP x (CZERONEZ y z))
34+ (OR (CZEROEQZ <t> ((ADD|SUB|OR|XOR|SUBW) x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23
35+ => ((ADD|SUB|OR|XOR|SUBW) x (CZERONEZ <t> y z))
36+ // (z != 0) ? ((OP x y)) : x => (OP x (CZEROEQZ y z))
37+ (OR (CZEROEQZ <t> ((ADD|SUB|OR|XOR|SUBW) x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23
38+ => ((ADD|SUB|OR|XOR|SUBW) x (CZEROEQZ <t> y z))
39+
40+ // AND-specific optimizations
41+ // (z == 0) ? (x & y) : x => OR(AND x y, CZEROEQZ x z)
42+ (OR (CZEROEQZ <t> (AND x y) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23
43+ => (OR (AND <t> x y) (CZEROEQZ <t> x z))
44+ // (z != 0) ? (x & y) : x => OR(AND x y, CZERONEZ x z)
45+ (OR (CZEROEQZ <t> (AND x y) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23
46+ => (OR (AND <t> x y) (CZERONEZ <t> x z))
47+
48+ // ANDI-specific optimizations (immediate version of AND)
49+ // (z == 0) ? (x & c) : x => OR(AND x c, CZEROEQZ x z)
50+ (OR (CZEROEQZ <t> (ANDI [c] x) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23
51+ => (OR (AND <t> x (MOVDconst [c])) (CZEROEQZ <t> x z))
52+ // (z != 0) ? (x & c) : x => OR(AND x c, CZERONEZ x z)
53+ (OR (CZEROEQZ <t> (ANDI [c] x) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23
54+ => (OR (AND <t> x (MOVDconst [c])) (CZERONEZ <t> x z))
55+
56+ // Immediate variants (64-bit only) - immediate is on the right
57+ // (z == 0) ? ((OPI [c] x)) : x => (OP x (CZERONEZ c z))
58+ (OR (CZEROEQZ <t> ((ADDI|ORI|XORI) [c] x) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23
59+ => ((ADD|OR|XOR) x (CZERONEZ <t> (MOVDconst [c]) z))
60+ // (z != 0) ? ((OPI [c] x)) : x => (OP x (CZEROEQZ c z))
61+ (OR (CZEROEQZ <t> ((ADDI|ORI|XORI) [c] x) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23
62+ => ((ADD|OR|XOR) x (CZEROEQZ <t> (MOVDconst [c]) z))
63+
64+ // 32-bit immediate variant (only ADDIW exists, no SUBIW/ORIW/XORIW/ANDIW)
65+ // (z == 0) ? (ADDIW [c] x) : x
66+ (OR (CZEROEQZ <t> (ADDIW [c] x) (SEQZ z)) (CZERONEZ <t> x (SEQZ z))) && buildcfg.GORISCV64 >= 23
67+ => (ADD x (CZERONEZ <t> (MOVDconst [int64(int32(c))]) z))
68+ // (z != 0) ? (ADDIW [c] x) : x
69+ (OR (CZEROEQZ <t> (ADDIW [c] x) (SNEZ z)) (CZERONEZ <t> x (SNEZ z))) && buildcfg.GORISCV64 >= 23
70+ => (ADD x (CZEROEQZ <t> (MOVDconst [int64(int32(c))]) z))
71+
72+ // Optimize conditional selection of constant or zero to single CZERO instruction
73+ // (cond == 0) ? 0 : const => CZERONEZ const cond
74+ (OR (CZEROEQZ <t> (MOVDconst [0]) (SEQZ cond)) (CZERONEZ <t> (MOVDconst [c]) (SEQZ cond))) && buildcfg.GORISCV64 >= 23
75+ => (CZERONEZ <t> (MOVDconst [c]) cond)
76+ // (cond != 0) ? 0 : const => CZEROEQZ const cond
77+ (OR (CZEROEQZ <t> (MOVDconst [0]) (SNEZ cond)) (CZERONEZ <t> (MOVDconst [c]) (SNEZ cond))) && buildcfg.GORISCV64 >= 23
78+ => (CZEROEQZ <t> (MOVDconst [c]) cond)
79+
80+ // Constant propagation through CZERO(EQ|NE)Z
81+ (CZERO(EQ|NE)Z <t> (MOVDconst [0]) _) && buildcfg.GORISCV64 >= 23 => (MOVDconst <t> [0])
0 commit comments