[llvm] [PowerPC] Exploit xxeval instruction for ternary patterns - part 1 (PR #141733)
Lei Huang via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 18 09:09:49 PDT 2025
================
@@ -2159,8 +2159,243 @@ let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
(COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
}
-class XXEvalPattern <dag pattern, bits<8> imm> :
- Pat<(v4i32 pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
+ // Defines a pattern for the XXEVAL instruction with a specific value type,
+ // pattern, and immediate.
+class XXEvalPattern <ValueType vt, dag pattern, bits<8> imm> :
+ Pat<(vt pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
+
+ // Helper class to generate unary NOT patterns for vector types.
+ // For v4i32, emits (vnot B) or (vnot C).
+ // For other types, bitcasts operand to v4i32, applies vnot, then bitcasts back.
+class XXEvalUnaryNotPattern<ValueType vt> {
+ dag vnotB = !if( !eq(vt, v4i32),
+ (vnot vt:$vB),
+ (vt (bitconvert (vnot (v4i32 (bitconvert vt:$vB)))))
+ );
+ dag vnotC = !if( !eq(vt, v4i32),
+ (vnot vt:$vC),
+ (vt (bitconvert (vnot (v4i32 (bitconvert vt:$vC)))))
+ );
+}
+
+ // Wrapper class for binary patterns with optional NOT on the result.
+ // If 'not' is 0, emits the binary op; if 1, emits vnot of the binary op.
+class XXEvalBinaryPattern<ValueType vt, SDPatternOperator op, bit not = 0> {
+ dag opPat = !if(!eq(not, 0),
+ // DAG for the binary operation.
+ !if(!eq(vt, v4i32),
+ (op vt:$vB, vt:$vC),
+ (vt (bitconvert (op (v4i32 (bitconvert vt:$vB)), (v4i32 (bitconvert vt:$vC)))))),
+ // DAG for the binary operation with a NOT applied to the result.
+ !if(!eq(vt, v4i32),
+ (vnot (op vt:$vB, vt:$vC)),
+ (vt (bitconvert (vnot (op (v4i32 (bitconvert vt:$vB)), (v4i32 (bitconvert vt:$vC))))))));
+}
+
+multiclass XXEvalVSelectWithXAnd<ValueType vt, bits<8> baseImm> {
+ // Multiclass for ternary patterns of the form vselect(A, X, and(B, C)).
+ // vselect(A, xor(B,C), and(B,C)) => imm = baseImm = 22
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ baseImm>;
+ // vselect(A, nor(B,C), and(B,C)) => imm = baseImm + 2 = 24
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 2)>;
+ // vselect(A, eqv(B,C), and(B,C)) => imm = baseImm + 3 = 25
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
----------------
lei137 wrote:
Maybe I am reading this wrong, but it seems you are using operations `and` which is defined to use gpr registers and bitconvert it to vector types? Seems these eval instructions all use vector types, shouldn't we be using the associated vector ops like `vand | vor` or this?
https://github.com/llvm/llvm-project/pull/141733
More information about the llvm-commits
mailing list