[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
Amy Kwan via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 28 12:01:18 PST 2024
================
@@ -16560,32 +16560,72 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
#include "llvm/TargetParser/PPCTargetParser.def"
auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx,
- unsigned CompOp,
+ unsigned Mask, unsigned CompOp,
unsigned OpValue) -> Value * {
if (SupportMethod == AIX_BUILTIN_PPC_FALSE)
return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
if (SupportMethod == AIX_BUILTIN_PPC_TRUE)
return llvm::ConstantInt::getTrue(ConvertType(E->getType()));
- assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod.");
- assert((CompOp == COMP_EQ) && "Only equal comparisons are supported.");
+ assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod.");
+
+ llvm::Value *FieldValue = nullptr;
+ if (SupportMethod == USE_SYS_CONF) {
+ llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE);
+ llvm::Constant *SysConf =
+ CGM.CreateRuntimeVariable(STy, "_system_configuration");
+
+ // Grab the appropriate field from _system_configuration.
+ llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
+ ConstantInt::get(Int32Ty, FieldIdx)};
+
+ FieldValue = Builder.CreateGEP(STy, SysConf, Idxs);
+ FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue,
+ CharUnits::fromQuantity(4));
+ } else if (SupportMethod == SYS_CALL) {
+ llvm::FunctionType *FTy =
+ llvm::FunctionType::get(Int64Ty, Int32Ty, false);
+ llvm::FunctionCallee Func =
+ CGM.CreateRuntimeFunction(FTy, "getsystemcfg");
+
+ FieldValue =
+ Builder.CreateCall(Func, {ConstantInt::get(Int32Ty, FieldIdx)});
+ }
+ assert((FieldValue != nullptr) &&
+ "unsupported SupportMethod defined in the PPCTargetParser.def.");
+
+ if (Mask)
+ FieldValue = Builder.CreateAnd(FieldValue, Mask);
- llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE);
- llvm::Constant *SysConf =
- CGM.CreateRuntimeVariable(STy, "_system_configuration");
+ CmpInst::Predicate PreOp;
+ switch (CompOp) {
+ case COMP_EQ:
+ PreOp = ICmpInst::ICMP_EQ;
+ break;
+ case COMP_GT:
+ PreOp = ICmpInst::ICMP_UGT;
+ break;
+ case COMP_GE:
+ PreOp = ICmpInst::ICMP_UGE;
+ break;
+ case COMP_NE:
+ PreOp = ICmpInst::ICMP_NE;
+ break;
+ default:
+ llvm_unreachable(
+ "Compare type does not match types defined in PPCTargetParser.def!");
+ }
- // Grab the appropriate field from _system_configuration.
- llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
- ConstantInt::get(Int32Ty, FieldIdx)};
+ llvm::Type *ValueType = FieldValue->getType();
+ assert(
+ (ValueType->isIntegerTy(64) || ValueType->isIntegerTy(32)) &&
----------------
amy-kwan wrote:
We can pull out `ValueType->isIntegerTy(64)` since we use it twice (here and below).
https://github.com/llvm/llvm-project/pull/82809
More information about the cfe-commits
mailing list