================
@@ -3063,14 +3026,93 @@ void CodeGenFunction::EmitMultiVersionResolver(
return;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
- case llvm::Triple::riscv32be:
- case llvm::Triple::riscv64be:
EmitRISCVMultiVersionResolver(Resolver, Options);
return;
-
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ if (getContext().getTargetInfo().getTriple().isOSAIX()) {
+ EmitPPCAIXMultiVersionResolver(Resolver, Options);
+ return;
+ }
+ [[fallthrough]];
default:
- assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
+ assert(false &&
+ "Only implemented for x86, AArch64, RISC-V, and PowerPC targets");
+ }
+}
+
+/**
+ * define internal ptr @foo.resolver() {
+ * entry:
+ * %is_version_1 = __builtin_cpu_supports(version_1)
+ * br i1 %1, label %if.version_1, label %if.else_2
+ *
+ * if.version_1:
+ * ret ptr @foo.version_1
+ *
+ * if.else_2:
+ * %is_version_2 = __builtin_cpu_supports(version_2)
+ * ...
+ * if.else: ; preds = %entry
+ * ret ptr @foo.default
+ * }
+ */
+void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
+
+ llvm::PointerType *PtrTy = Builder.getPtrTy();
+ // entry:
+ llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);
+
+ SmallVector<std::pair<llvm::Value *, llvm::BasicBlock *>, 3> PhiArgs;
+ for (const FMVResolverOption &RO : Options) {
+ Builder.SetInsertPoint(CurBlock);
+ // The 'default' or 'generic' case.
+ if (!RO.Architecture && RO.Features.empty()) {
+ // if.else:
+ // ret ptr @foo.default
+ assert(&RO == Options.end() - 1 &&
+ "Default or Generic case must be last");
+ Builder.CreateRet(RO.Function);
+ break;
+ }
+ // if.else_n:
+ // %is_version_n = __builtin_cpu_supports(version_n)
+ // br i1 %is_version_n, label %if.version_n, label %if.else_n+1
+ //
+ // if.version_n:
+ // ret ptr @foo_version_n
+ assert(RO.Features.size() == 1 &&
+ "for now one feature requirement per version");
+
+ assert(RO.Features[0].starts_with("cpu="));
+ StringRef CPU = RO.Features[0].split("=").second.trim();
+ StringRef Feature = llvm::StringSwitch<StringRef>(CPU)
+ .Case("pwr7", "arch_2_06")
+ .Case("pwr8", "arch_2_07")
+ .Case("pwr9", "arch_3_00")
+ .Case("pwr10", "arch_3_1")
+ .Case("pwr11", "arch_3_1")
+ .Default("error");
----------------
w2yehia wrote:
The above list (pwr7 - pwr11) is what we support/care about on AIX.
at the moment, with the PR as is, we will accept the following CPUs:
`440,440fp,ppc440,ppc405,ppc464,ppc476,970,ppc970,a2,ppca2,ppc-cell-be,pwr4,power4,pwr5,power5,pwr5+,power5+,pwr6,power6,pwr6x,power6x`
generate clones for them but not generate checks for them in the resolver (also
the __builtin_cpu_is accepts them and answers `false` statically, and we reuse
the decision logic).
https://github.com/llvm/llvm-project/pull/177428
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits