@@ -346,7 +346,7 @@ template <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
346
346
// / This helper class is used to match constant scalars, vector splats,
347
347
// / and fixed width vectors that satisfy a specified predicate.
348
348
// / For fixed width vector constants, undefined elements are ignored.
349
- template <typename Predicate, typename ConstantVal>
349
+ template <typename Predicate, typename ConstantVal, bool AllowUndefs >
350
350
struct cstval_pred_ty : public Predicate {
351
351
template <typename ITy> bool match (ITy *V) {
352
352
if (const auto *CV = dyn_cast<ConstantVal>(V))
@@ -369,8 +369,11 @@ struct cstval_pred_ty : public Predicate {
369
369
Constant *Elt = C->getAggregateElement (i);
370
370
if (!Elt)
371
371
return false ;
372
- if (isa<UndefValue>(Elt))
372
+ if (isa<UndefValue>(Elt)) {
373
+ if (!AllowUndefs)
374
+ return false ;
373
375
continue ;
376
+ }
374
377
auto *CV = dyn_cast<ConstantVal>(Elt);
375
378
if (!CV || !this ->isValue (CV->getValue ()))
376
379
return false ;
@@ -384,16 +387,17 @@ struct cstval_pred_ty : public Predicate {
384
387
};
385
388
386
389
// / specialization of cstval_pred_ty for ConstantInt
387
- template <typename Predicate>
388
- using cst_pred_ty = cstval_pred_ty<Predicate, ConstantInt>;
390
+ template <typename Predicate, bool AllowUndefs = true >
391
+ using cst_pred_ty = cstval_pred_ty<Predicate, ConstantInt, AllowUndefs >;
389
392
390
393
// / specialization of cstval_pred_ty for ConstantFP
391
- template <typename Predicate>
392
- using cstfp_pred_ty = cstval_pred_ty<Predicate, ConstantFP>;
394
+ template <typename Predicate, bool AllowUndefs = true >
395
+ using cstfp_pred_ty = cstval_pred_ty<Predicate, ConstantFP, AllowUndefs >;
393
396
394
397
// / This helper class is used to match scalar and vector constants that
395
398
// / satisfy a specified predicate, and bind them to an APInt.
396
- template <typename Predicate> struct api_pred_ty : public Predicate {
399
+ template <typename Predicate, bool AllowUndefs = true >
400
+ struct api_pred_ty : public Predicate {
397
401
const APInt *&Res;
398
402
399
403
api_pred_ty (const APInt *&R) : Res(R) {}
@@ -406,7 +410,8 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
406
410
}
407
411
if (V->getType ()->isVectorTy ())
408
412
if (const auto *C = dyn_cast<Constant>(V))
409
- if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue ()))
413
+ if (auto *CI =
414
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue (AllowUndefs)))
410
415
if (this ->isValue (CI->getValue ())) {
411
416
Res = &CI->getValue ();
412
417
return true ;
@@ -419,7 +424,8 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
419
424
// / This helper class is used to match scalar and vector constants that
420
425
// / satisfy a specified predicate, and bind them to an APFloat.
421
426
// / Undefs are allowed in splat vector constants.
422
- template <typename Predicate> struct apf_pred_ty : public Predicate {
427
+ template <typename Predicate, bool AllowUndefs = true >
428
+ struct apf_pred_ty : public Predicate {
423
429
const APFloat *&Res;
424
430
425
431
apf_pred_ty (const APFloat *&R) : Res(R) {}
@@ -432,8 +438,8 @@ template <typename Predicate> struct apf_pred_ty : public Predicate {
432
438
}
433
439
if (V->getType ()->isVectorTy ())
434
440
if (const auto *C = dyn_cast<Constant>(V))
435
- if (auto *CI = dyn_cast_or_null<ConstantFP>(
436
- C->getSplatValue (/* AllowUndef */ true )))
441
+ if (auto *CI =
442
+ dyn_cast_or_null<ConstantFP>( C->getSplatValue (AllowUndefs )))
437
443
if (this ->isValue (CI->getValue ())) {
438
444
Res = &CI->getValue ();
439
445
return true ;
@@ -452,6 +458,69 @@ template <typename Predicate> struct apf_pred_ty : public Predicate {
452
458
//
453
459
// /////////////////////////////////////////////////////////////////////////////
454
460
461
+ template <typename APTy> struct custom_checkfn {
462
+ function_ref<bool (const APTy &)> CheckFn;
463
+ bool isValue (const APTy &C) { return CheckFn (C); }
464
+ };
465
+
466
+ // Match and integer or vector where CheckFn(ele) for each element is true.
467
+ // For vectors, undefined elements are assumed NOT to match.
468
+ inline cst_pred_ty<custom_checkfn<APInt>, false >
469
+ m_CheckedInt (function_ref<bool (const APInt &)> CheckFn) {
470
+ return cst_pred_ty<custom_checkfn<APInt>, false >{CheckFn};
471
+ }
472
+
473
+ inline api_pred_ty<custom_checkfn<APInt>, false >
474
+ m_CheckedInt (const APInt *&V, function_ref<bool (const APInt &)> CheckFn) {
475
+ api_pred_ty<custom_checkfn<APInt>, false > P (V);
476
+ P.CheckFn = CheckFn;
477
+ return P;
478
+ }
479
+
480
+ // Match and integer or vector where CheckFn(ele) for each element is true.
481
+ // For vectors, undefined elements are assumed to match.
482
+ inline cst_pred_ty<custom_checkfn<APInt>>
483
+ m_CheckedIntAllowUndef (function_ref<bool (const APInt &)> CheckFn) {
484
+ return cst_pred_ty<custom_checkfn<APInt>>{CheckFn};
485
+ }
486
+
487
+ inline api_pred_ty<custom_checkfn<APInt>>
488
+ m_CheckedIntAllowUndef (const APInt *&V,
489
+ function_ref<bool (const APInt &)> CheckFn) {
490
+ api_pred_ty<custom_checkfn<APInt>> P (V);
491
+ P.CheckFn = CheckFn;
492
+ return P;
493
+ }
494
+
495
+ // Match and float or vector where CheckFn(ele) for each element is true.
496
+ // For vectors, undefined elements are assumed NOT to match.
497
+ inline cstfp_pred_ty<custom_checkfn<APFloat>, false >
498
+ m_CheckedFp (function_ref<bool (const APFloat &)> CheckFn) {
499
+ return cstfp_pred_ty<custom_checkfn<APFloat>, false >{CheckFn};
500
+ }
501
+
502
+ inline apf_pred_ty<custom_checkfn<APFloat>, false >
503
+ m_CheckedFp (const APFloat *&V, function_ref<bool (const APFloat &)> CheckFn) {
504
+ apf_pred_ty<custom_checkfn<APFloat>, false > P (V);
505
+ P.CheckFn = CheckFn;
506
+ return P;
507
+ }
508
+
509
+ // Match and float or vector where CheckFn(ele) for each element is true.
510
+ // For vectors, undefined elements are assumed to match.
511
+ inline cstfp_pred_ty<custom_checkfn<APFloat>>
512
+ m_CheckedFpAllowUndef (function_ref<bool (const APFloat &)> CheckFn) {
513
+ return cstfp_pred_ty<custom_checkfn<APFloat>>{CheckFn};
514
+ }
515
+
516
+ inline apf_pred_ty<custom_checkfn<APFloat>>
517
+ m_CheckedFpAllowUndef (const APFloat *&V,
518
+ function_ref<bool (const APFloat &)> CheckFn) {
519
+ apf_pred_ty<custom_checkfn<APFloat>> P (V);
520
+ P.CheckFn = CheckFn;
521
+ return P;
522
+ }
523
+
455
524
struct is_any_apint {
456
525
bool isValue (const APInt &C) { return true ; }
457
526
};
0 commit comments