diff options
author | Dávid Bolvanský <david.bolvansky@gmail.com> | 2023-06-01 20:56:12 +0200 |
---|---|---|
committer | Dávid Bolvanský <david.bolvansky@gmail.com> | 2023-06-01 20:56:44 +0200 |
commit | 09515f2c20111628ce81ad5f40e12e5f6af5ed2f (patch) | |
tree | 865d85bf16fdb7920b69678ee969baf7a4f07452 /llvm/lib/CodeGen/MachineInstr.cpp | |
parent | 0a21fb3441dcffa2ccd8215f423100fbe4182f12 (diff) | |
download | llvm-09515f2c20111628ce81ad5f40e12e5f6af5ed2f.zip llvm-09515f2c20111628ce81ad5f40e12e5f6af5ed2f.tar.gz llvm-09515f2c20111628ce81ad5f40e12e5f6af5ed2f.tar.bz2 |
[SDAG] Preserve unpredictable metadata, teach X86CmovConversion to respect this metadata
Sometimes an developer would like to have more control over cmov vs branch. We have unpredictable metadata in LLVM IR, but currently it is ignored by X86 backend. Propagate this metadata and avoid cmov->branch conversion in X86CmovConversion for cmov with this metadata.
Example:
```
int MaxIndex(int n, int *a) {
int t = 0;
for (int i = 1; i < n; i++) {
// cmov is converted to branch by X86CmovConversion
if (a[i] > a[t]) t = i;
}
return t;
}
int MaxIndex2(int n, int *a) {
int t = 0;
for (int i = 1; i < n; i++) {
// cmov is preserved
if (__builtin_unpredictable(a[i] > a[t])) t = i;
}
return t;
}
```
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D118118
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineInstr.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index f296533..400e76f 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -534,14 +534,14 @@ void MachineInstr::cloneInstrSymbols(MachineFunction &MF, setPCSections(MF, MI.getPCSections()); } -uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { +uint32_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { // For now, the just return the union of the flags. If the flags get more // complicated over time, we might need more logic here. return getFlags() | Other.getFlags(); } -uint16_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { - uint16_t MIFlags = 0; +uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { + uint32_t MIFlags = 0; // Copy the wrapping flags. if (const OverflowingBinaryOperator *OB = dyn_cast<OverflowingBinaryOperator>(&I)) { @@ -575,6 +575,9 @@ uint16_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { MIFlags |= MachineInstr::MIFlag::FmReassoc; } + if (I.getMetadata(LLVMContext::MD_unpredictable)) + MIFlags |= MachineInstr::MIFlag::Unpredictable; + return MIFlags; } |