[clang] [llvm] [FMV][AIX] Implement target_clones part 2 (target-features) (PR #206786)
Wael Yehia via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 16 10:16:03 PDT 2026
================
@@ -3140,18 +3137,53 @@ void CodeGenFunction::EmitPPCAIXMultiVersionResolver(
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");
-
- llvm::Value *Condition = EmitPPCBuiltinCpu(
- Builtin::BI__builtin_cpu_supports, Builder.getInt1Ty(), Feature);
+ StringRef FeatureStr = RO.Features[0];
+ StringRef BuiltinCpuSupportsArg;
+ bool IsNegated = false;
+
+ if (FeatureStr.starts_with("cpu=")) {
+ // CPU specification - map to ISA level
+ StringRef CPU = FeatureStr.split("=").second.trim();
+ BuiltinCpuSupportsArg = llvm::StringSwitch<StringRef>(CPU)
+#define PPC_AIX_CLONES_CPU(CPU_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME, _) \
+ .Case(CPU_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME)
+#include "llvm/TargetParser/PPCTargetParser.def"
+ .Default("error");
+ } else {
+ // Feature strings arrive here already normalized:
+ // - Positive features: just the name (e.g., "altivec")
+ // - Negated features: "no-" prefix (e.g., "no-altivec")
+ if (FeatureStr.starts_with("no-")) {
+ IsNegated = true;
+ FeatureStr = FeatureStr.drop_front(3);
+ }
----------------
w2yehia wrote:
@diggerlin suggested that negative features should have highest priority.
I think in the absence of a priority field (RISC-V has [one](https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc#__attribute__target_clonestarget-clones-attr-string-)), it makes sense to treat a negative feature requirement as a correctness requirement which should take higher precedence than selecting for performance.
Thinking about this more, you can divide features into 3 categories:
1) non-CPU properties (e.g. `invariant-function-descriptors`); those cannot be tested at runtime, and are currently excluded from the list of valid target_clones.
2) CPU properties that cannot be disabled (e.g. mma); you obviously cannot enable a feature on a CPU that doesn't physically support it, so those features can map to CPUs directly.
`+feature` => `__builtin_cpu_supports("<minimum-cpu>")` => true for CPU `<minimum-cpu>` and above.
`-feature` => `!__builtin_cpu_supports("<minimum-cpu>")` => true for CPU `<minimum-cpu-minus-one>` and below.
3) CPU properties that can be disabled (e.g. vsx); those can map to CPUs directly for the positive requirement (same as (2); for the negative requirement checking the CPU is incorrect, and there needs to be a way to check the property directly. So we should only support `-feature` for the ones that can be tested, and for now it is `vsx`, `altivec`, and `htm` from my investigation.
This still leaves the following scenario broken if at runtime both features are disabled but each clone only has one of the two features disabled and the other enabled.
```
__attribute__((target_clones("no-htm","no-vsx,"default")))
int foo(void) { return 4; }
```
You can argue this is a limitation as a result of limiting the clone to one requirement.
Expanding to multiple requirements is another discussion for future work.
I will implement the above.
@diggerlin what do you think?
https://github.com/llvm/llvm-project/pull/206786
More information about the cfe-commits
mailing list