@@ -2159,8 +2159,131 @@ let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
2159
2159
(COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
2160
2160
}
2161
2161
2162
- class xxevalPattern <dag pattern, bits<8> imm> :
2163
- Pat<(v4i32 pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
2162
+ class xxevalPattern <ValueType vt, dag pattern, bits<8> imm> :
2163
+ Pat<(vt pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
2164
+
2165
+ class DagCondVNot<dag d, bit negate> {
2166
+ // Utility to define a vnot around the dag.
2167
+ dag res = !if(!ne(negate, 0),
2168
+ (vnot d),
2169
+ d);
2170
+ }
2171
+
2172
+ class XXEvalUnaryPattern<ValueType vt> {
2173
+ // vnot Operand B
2174
+ dag vnotB = !cond(
2175
+ !eq(vt, v4i32) : (vnot v4i32:$vB),
2176
+ !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vB)))))
2177
+ );
2178
+ // vnot Operand C
2179
+ dag vnotC = !cond(
2180
+ !eq(vt, v4i32) : (vnot v4i32:$vC),
2181
+ !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vC)))))
2182
+ );
2183
+ }
2184
+
2185
+ class XXEvalBinaryPattern<ValueType vt, SDPatternOperator op, bit notResult = 0> {
2186
+ // Defines a wrapper class for binary patterns with optional NOT on result.
2187
+ // Generate op pattern with optional NOT wrapping for result depending on "notResult".
2188
+ dag opPat = !cond(
2189
+ !eq(vt, v4i32) : DagCondVNot<(op v4i32:$vB, v4i32:$vC), notResult>.res,
2190
+ !eq(vt, v2i64) : (v2i64 (bitconvert DagCondVNot<(op
2191
+ (v4i32 (bitconvert v2i64:$vB)),
2192
+ (v4i32 (bitconvert v2i64:$vC))), notResult>.res))
2193
+ );
2194
+ }
2195
+
2196
+ multiclass XXEvalVSelectWithXAnd<ValueType vt, bits<8> baseImm> {
2197
+ // Multiclass for Ternary(A, X, and(B, C)) style patterns.
2198
+ // Ternary(A, xor(B,C), and(B,C)) => imm: baseImm
2199
+ def : xxevalPattern<vt,
2200
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
2201
+ baseImm>;
2202
+ // Ternary(A, nor(B,C), and(B,C)) => imm: baseImm + 2
2203
+ def : xxevalPattern<vt,
2204
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
2205
+ !add(baseImm, 2)>;
2206
+ // Ternary(A, eqv(B,C), and(B,C)) => imm: baseImm + 3
2207
+ def : xxevalPattern<vt,
2208
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
2209
+ !add(baseImm, 3)>;
2210
+ // Ternary(A, not(C), and(B,C)) => imm: baseImm + 4
2211
+ def : xxevalPattern<vt,
2212
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, XXEvalBinaryPattern<vt, and>.opPat),
2213
+ !add(baseImm, 4)>;
2214
+ // Ternary(A, not(B), and(B,C)) => imm: baseImm + 6
2215
+ def : xxevalPattern<vt,
2216
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotB, XXEvalBinaryPattern<vt, and>.opPat),
2217
+ !add(baseImm, 6)>;
2218
+ }
2219
+
2220
+ multiclass XXEvalVSelectWithXB<ValueType vt, bits<8> baseImm>{
2221
+ // Multiclass for Ternary(A, X, B) style patterns
2222
+ // Ternary(A, and(B,C), B) => imm: baseImm
2223
+ def : xxevalPattern<vt,
2224
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vB),
2225
+ baseImm>;
2226
+ // Ternary(A, nor(B,C), B) => imm: baseImm + 7
2227
+ def : xxevalPattern<vt,
2228
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vB),
2229
+ !add(baseImm, 7)>;
2230
+ // Ternary(A, eqv(B,C), B) => imm: baseImm + 8
2231
+ def : xxevalPattern<vt,
2232
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vB),
2233
+ !add(baseImm, 8)>;
2234
+ // Ternary(A, not(C), B) => imm: baseImm + 9
2235
+ def : xxevalPattern<vt,
2236
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, vt:$vB),
2237
+ !add(baseImm, 9)>;
2238
+ // Ternary(A, nand(B,C), B) => imm: baseImm + 13
2239
+ def : xxevalPattern<vt,
2240
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vB),
2241
+ !add(baseImm, 13)>;
2242
+ }
2243
+
2244
+ multiclass XXEvalVSelectWithXC<ValueType vt, bits<8> baseImm>{
2245
+ // Multiclass for Ternary(A, X, C) style patterns
2246
+ // Ternary(A, and(B,C), C) => imm: baseImm
2247
+ def : xxevalPattern<vt,
2248
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vC),
2249
+ baseImm>;
2250
+ // Ternary(A, nor(B,C), C) => imm: baseImm + 7
2251
+ def : xxevalPattern<vt,
2252
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vC),
2253
+ !add(baseImm, 7)>;
2254
+ // Ternary(A, eqv(B,C), C) => imm: baseImm + 8
2255
+ def : xxevalPattern<vt,
2256
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vC),
2257
+ !add(baseImm, 8)>;
2258
+ // Ternary(A, nand(B,C), C) => imm: baseImm + 13
2259
+ def : xxevalPattern<vt,
2260
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vC),
2261
+ !add(baseImm, 13)>;
2262
+ }
2263
+
2264
+ multiclass XXEvalVSelectWithXXor<ValueType vt, bits<8> baseImm>{
2265
+ // Multiclass for Ternary(A, X, xor(B,C)) style patterns
2266
+ // Ternary(A, and(B,C), xor(B,C)) => imm: baseImm
2267
+ def : xxevalPattern<vt,
2268
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
2269
+ baseImm>;
2270
+ // Ternary(A, B, xor(B,C)) => imm: baseImm + 2
2271
+ def : xxevalPattern<vt,
2272
+ (vselect vt:$vA, vt:$vB, XXEvalBinaryPattern<vt, xor>.opPat),
2273
+ !add(baseImm, 2)>;
2274
+ // Ternary(A, C, xor(B,C)) => imm: baseImm + 4
2275
+ def : xxevalPattern<vt,
2276
+ (vselect vt:$vA, vt:$vC, XXEvalBinaryPattern<vt, xor>.opPat),
2277
+ !add(baseImm, 4)>;
2278
+ // Ternary(A, or(B,C), xor(B,C)) => imm: baseImm + 6
2279
+ def : xxevalPattern<vt,
2280
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
2281
+ !add(baseImm, 6)>;
2282
+ // Ternary(A, nor(B,C), xor(B,C)) => imm: baseImm + 7
2283
+ def : xxevalPattern<vt,
2284
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
2285
+ !add(baseImm, 7)>;
2286
+ }
2164
2287
2165
2288
let Predicates = [PrefixInstrs, HasP10Vector] in {
2166
2289
let AddedComplexity = 400 in {
@@ -2192,83 +2315,96 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
2192
2315
// Anonymous patterns for XXEVAL
2193
2316
// AND
2194
2317
// and(A, B, C)
2195
- def : xxevalPattern<(and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
2318
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
2196
2319
// and(A, xor(B, C))
2197
- def : xxevalPattern<(and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
2320
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
2198
2321
// and(A, or(B, C))
2199
- def : xxevalPattern<(and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
2322
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
2200
2323
// and(A, nor(B, C))
2201
- def : xxevalPattern<(and v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 8>;
2324
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 8>;
2202
2325
// and(A, eqv(B, C))
2203
- def : xxevalPattern<(and v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 9>;
2326
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 9>;
2204
2327
// and(A, nand(B, C))
2205
- def : xxevalPattern<(and v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 14>;
2328
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 14>;
2206
2329
2207
2330
// NAND
2208
2331
// nand(A, B, C)
2209
- def : xxevalPattern<(vnot (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
2332
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
2210
2333
!sub(255, 1)>;
2211
2334
// nand(A, xor(B, C))
2212
- def : xxevalPattern<(vnot (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
2335
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
2213
2336
!sub(255, 6)>;
2214
2337
// nand(A, or(B, C))
2215
- def : xxevalPattern<(vnot (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
2338
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
2216
2339
!sub(255, 7)>;
2217
2340
// nand(A, nor(B, C))
2218
- def : xxevalPattern<(or (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
2341
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
2219
2342
!sub(255, 8)>;
2220
2343
// nand(A, eqv(B, C))
2221
- def : xxevalPattern<(or (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
2344
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
2222
2345
!sub(255, 9)>;
2223
2346
// nand(A, nand(B, C))
2224
- def : xxevalPattern<(or (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
2347
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
2225
2348
!sub(255, 14)>;
2226
2349
2227
2350
// EQV
2228
2351
// (eqv A, B, C)
2229
- def : xxevalPattern<(or (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)),
2352
+ def : xxevalPattern<v4i32, (or (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)),
2230
2353
(vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)))),
2231
2354
150>;
2232
2355
// (eqv A, (and B, C))
2233
- def : xxevalPattern<(vnot (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 225>;
2356
+ def : xxevalPattern<v4i32, (vnot (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 225>;
2234
2357
// (eqv A, (or B, C))
2235
- def : xxevalPattern<(vnot (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 135>;
2358
+ def : xxevalPattern<v4i32, (vnot (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 135>;
2236
2359
2237
2360
// NOR
2238
2361
// (nor A, B, C)
2239
- def : xxevalPattern<(vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 128>;
2362
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 128>;
2240
2363
// (nor A, (and B, C))
2241
- def : xxevalPattern<(vnot (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 224>;
2364
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 224>;
2242
2365
// (nor A, (eqv B, C))
2243
- def : xxevalPattern<(and (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)), 96>;
2366
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)), 96>;
2244
2367
// (nor A, (nand B, C))
2245
- def : xxevalPattern<(and (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)), 16>;
2368
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)), 16>;
2246
2369
// (nor A, (nor B, C))
2247
- def : xxevalPattern<(and (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)), 112>;
2370
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)), 112>;
2248
2371
// (nor A, (xor B, C))
2249
- def : xxevalPattern<(vnot (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))), 144>;
2372
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))), 144>;
2250
2373
2251
2374
// OR
2252
2375
// (or A, B, C)
2253
- def : xxevalPattern<(or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 127>;
2376
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 127>;
2254
2377
// (or A, (and B, C))
2255
- def : xxevalPattern<(or v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 31>;
2378
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 31>;
2256
2379
// (or A, (eqv B, C))
2257
- def : xxevalPattern<(or v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 159>;
2380
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 159>;
2258
2381
// (or A, (nand B, C))
2259
- def : xxevalPattern<(or v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 239>;
2382
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 239>;
2260
2383
// (or A, (nor B, C))
2261
- def : xxevalPattern<(or v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 143>;
2384
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 143>;
2262
2385
// (or A, (xor B, C))
2263
- def : xxevalPattern<(or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 111>;
2386
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 111>;
2264
2387
2265
2388
// XOR
2266
2389
// (xor A, B, C)
2267
- def : xxevalPattern<(xor v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 105>;
2390
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 105>;
2268
2391
// (xor A, (and B, C))
2269
- def : xxevalPattern<(xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 30>;
2392
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 30>;
2270
2393
// (xor A, (or B, C))
2271
- def : xxevalPattern<(xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 120>;
2394
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 120>;
2395
+
2396
+ // Utilize xxeval instruction for ternary vector expressions.
2397
+ defm : XXEvalVSelectWithXAnd<v4i32, 22>;
2398
+ defm : XXEvalVSelectWithXAnd<v2i64, 22>;
2399
+
2400
+ defm : XXEvalVSelectWithXB<v4i32, 49>;
2401
+ defm : XXEvalVSelectWithXB<v2i64, 49>;
2402
+
2403
+ defm : XXEvalVSelectWithXC<v4i32, 81>;
2404
+ defm : XXEvalVSelectWithXC<v2i64, 81>;
2405
+
2406
+ defm : XXEvalVSelectWithXXor<v4i32, 97>;
2407
+ defm : XXEvalVSelectWithXXor<v2i64, 97>;
2272
2408
2273
2409
// Anonymous patterns to select prefixed VSX loads and stores.
2274
2410
// Load / Store f128
0 commit comments