Skip to content

[Clang] VectorExprEvaluator::VisitCallExpr - add x86 __builtin_ia32_select* constexpr handling #152321

@RKSimon

Description

@RKSimon

The following builtins need to be handled in constexpr to allow us to constexpr the avx512 predicated intrinsics:

 X86::BI__builtin_ia32_selectb_128:
 X86::BI__builtin_ia32_selectb_256:
 X86::BI__builtin_ia32_selectb_512:
 X86::BI__builtin_ia32_selectw_128:
 X86::BI__builtin_ia32_selectw_256:
 X86::BI__builtin_ia32_selectw_512:
 X86::BI__builtin_ia32_selectd_128:
 X86::BI__builtin_ia32_selectd_256:
 X86::BI__builtin_ia32_selectd_512:
 X86::BI__builtin_ia32_selectq_128:
 X86::BI__builtin_ia32_selectq_256:
 X86::BI__builtin_ia32_selectq_512:
 X86::BI__builtin_ia32_selectph_128:
 X86::BI__builtin_ia32_selectph_256:
 X86::BI__builtin_ia32_selectph_512:
 X86::BI__builtin_ia32_selectpbf_128:
 X86::BI__builtin_ia32_selectpbf_256:
 X86::BI__builtin_ia32_selectpbf_512:
 X86::BI__builtin_ia32_selectps_128:
 X86::BI__builtin_ia32_selectps_256:
 X86::BI__builtin_ia32_selectps_512:
 X86::BI__builtin_ia32_selectpd_128:
 X86::BI__builtin_ia32_selectpd_256:
 X86::BI__builtin_ia32_selectpd_512:

The expansion isn't too difficult:

static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
unsigned NumElts) {
auto *MaskTy = llvm::FixedVectorType::get(
CGF.Builder.getInt1Ty(),
cast<IntegerType>(Mask->getType())->getBitWidth());
Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
// If we have less than 8 elements, then the starting mask was an i8 and
// we need to extract down to the right number of elements.
if (NumElts < 8) {
int Indices[4];
for (unsigned i = 0; i != NumElts; ++i)
Indices[i] = i;
MaskVec = CGF.Builder.CreateShuffleVector(
MaskVec, MaskVec, ArrayRef(Indices, NumElts), "extract");
}
return MaskVec;
}

static Value *EmitX86Select(CodeGenFunction &CGF,
Value *Mask, Value *Op0, Value *Op1) {
// If the mask is all ones just return first argument.
if (const auto *C = dyn_cast<Constant>(Mask))
if (C->isAllOnesValue())
return Op0;
Mask = getMaskVecValue(
CGF, Mask, cast<llvm::FixedVectorType>(Op0->getType())->getNumElements());
return CGF.Builder.CreateSelect(Mask, Op0, Op1);
}

ExprConstant.cpp already has precedent for handling target specific builtins (the x86 BMI intrinsics), so hopefully this isn't controversial.

Metadata

Metadata

Assignees

Labels

backend:X86clang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationgood first issuehttps://github.com/llvm/llvm-project/contribute

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions