================
@@ -22505,6 +22506,57 @@ Value 
*CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
   return nullptr;
 }
 
+Value *CodeGenFunction::EmitRISCVCpuIs(const CallExpr *E) {
+  const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
+  StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
+  return EmitRISCVCpuIs(CPUStr);
+}
+
+Value *CodeGenFunction::EmitRISCVCpuIs(StringRef CPUStr) {
+  llvm::Type *Int32Ty = Builder.getInt32Ty();
+  llvm::Type *Int64Ty = Builder.getInt64Ty();
+  llvm::Type *MXLenType =
+      CGM.getTarget().getTriple().isArch32Bit() ? Int32Ty : Int64Ty;
+
+  llvm::Type *StructTy = llvm::StructType::get(Int32Ty, MXLenType, MXLenType);
+  llvm::Constant *RISCVCPUModel =
+      CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model");
+  cast<llvm::GlobalValue>(RISCVCPUModel)->setDSOLocal(true);
+
+  auto loadRISCVCPUID = [&](unsigned Index, llvm::Type *ValueTy,
+                            CGBuilderTy &Builder, CodeGenModule &CGM) {
+    llvm::Value *GEPIndices[] = {Builder.getInt32(0),
+                                 llvm::ConstantInt::get(Int32Ty, Index)};
+    Value *Ptr = Builder.CreateInBoundsGEP(StructTy, RISCVCPUModel, 
GEPIndices);
+    Value *CPUID = Builder.CreateAlignedLoad(
+        ValueTy, Ptr,
+        CharUnits::fromQuantity(ValueTy->getScalarSizeInBits() / 8));
+    return CPUID;
+  };
+
+  // Compare mvendorid.
+  Value *VendorID = loadRISCVCPUID(0, Int32Ty, Builder, CGM);
+  Value *Result = Builder.CreateICmpEQ(
+      VendorID,
+      llvm::ConstantInt::get(Int32Ty, llvm::RISCV::getVendorID(CPUStr)));
+
+  // Compare marchid.
+  Value *ArchID = loadRISCVCPUID(1, MXLenType, Builder, CGM);
+  Result = Builder.CreateAnd(
+      Result, Builder.CreateICmpEQ(
+                  ArchID, llvm::ConstantInt::get(
+                              MXLenType, llvm::RISCV::getArchID(CPUStr))));
+
+  // Compare mimplid.
+  Value *ImplID = loadRISCVCPUID(2, MXLenType, Builder, CGM);
+  Result = Builder.CreateAnd(
+      Result, Builder.CreateICmpEQ(
+                  ImplID, llvm::ConstantInt::get(
+                              MXLenType, llvm::RISCV::getImplID(CPUStr))));
----------------
lenary wrote:

Currently we are using `getVendorID`, `getArchID` or `getImplID` returning 0 to 
mean we have no IDs in LLVM for that CPU. On the CPU Core's side, the CSRs will 
also report 0 if they are not implemented (though I'm not sure what e.g. Linux 
reports to userspace in this case).

When we have no IDs, what comparisons should we be doing?

Maybe we should only support `__builtin_cpu_is(...)` for CPUs where we have 
non-zero values for any of the three items? Otherwise either emit a 
compile-time error, or return `false` because we don't have a way to actually 
know if we're on the CPU being asked for?

I don't know the right answer here, but I think this implementation isn't 
handling these cases right.


https://github.com/llvm/llvm-project/pull/116231
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to