[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)

Amy Kwan via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 13:34:44 PST 2024


================
@@ -16560,32 +16560,69 @@ 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)});
+    }
+
+    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 is not correct 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();
----------------
amy-kwan wrote:

Might be a dumb question, but `FieldValue` is initially set to `nullptr` initially and only gets set in two separate conditions. I assume we expect `FieldValue` is be non-null at this point, and if so, is something like an `assert()` needed here?

https://github.com/llvm/llvm-project/pull/82809


More information about the cfe-commits mailing list