[llvm] [llvm] Fix enum-enum bitwise and arithmetic conversions for C++26 (PR #228945)

via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 4 15:30:17 PDT 2026


https://github.com/rdong8 created https://github.com/llvm/llvm-project/pull/228945

Fixes arithmetic operations between enumerators of different enum types that are now rejected under C++26. 

Assisted by AI.

Related:
- https://github.com/llvm/llvm-project/pull/223284
- https://discourse.llvm.org/t/policy-on-supporting-newer-c-standard-in-llvm-codebase/88114

>From 6f6aff0c499fd2fae808a1d63e293eefd2aa6fe7 Mon Sep 17 00:00:00 2001
From: Richard Dong <rdong8 at protonmail.com>
Date: Sun, 4 Oct 2026 20:36:39 +0000
Subject: [PATCH] [llvm] Fix enum-enum bitwise and arithmetic conversions for
 C++26

Fix operations involving distinct enum types across LLVM target descriptors,
MC, and CodeGen that are deprecated or rejected under C++26:
- Use llvm::to_underlying for fixup arithmetic and MachO section attributes.
- Use explicit comparison for InlineAsm dialect flags rather than enum arithmetic.
- Define operator& for PPC Predicate and BranchHintBit.
---
 llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp      |  3 ++-
 llvm/lib/CodeGen/SelectionDAG/FastISel.cpp             |  3 ++-
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp  |  3 ++-
 llvm/lib/MC/MCObjectFileInfo.cpp                       |  4 ++--
 llvm/lib/MC/MCParser/DarwinAsmParser.cpp               |  8 ++++----
 llvm/lib/Target/AMDGPU/SIFrameLowering.cpp             |  4 ++--
 llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp     |  2 +-
 .../LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp     |  2 +-
 .../LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp  |  2 +-
 .../lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp |  2 +-
 llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h   | 10 ++++++++++
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp |  2 +-
 .../SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp      |  2 +-
 llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp  |  2 +-
 14 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index 19eae930cc26b10..01bd7c28595fec8 100644
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -69,7 +69,8 @@ class ExtraFlags {
       Flags |= InlineAsm::Extra_MayUnwind;
     if (CB.isConvergent())
       Flags |= InlineAsm::Extra_IsConvergent;
-    Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
+    if (IA->getDialect() == InlineAsm::AD_Intel)
+      Flags |= InlineAsm::Extra_AsmDialect;
   }
 
   void update(const TargetLowering::AsmOperandInfo &OpInfo) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 4f3913907050812..19f1f328d309b1b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1171,7 +1171,8 @@ bool FastISel::selectCall(const User *I) {
       ExtraInfo |= InlineAsm::Extra_MayUnwind;
     if (Call->isConvergent())
       ExtraInfo |= InlineAsm::Extra_IsConvergent;
-    ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
+    if (IA->getDialect() == InlineAsm::AD_Intel)
+      ExtraInfo |= InlineAsm::Extra_AsmDialect;
 
     MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
                                       TII.get(TargetOpcode::INLINEASM));
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index dfbf9a401b53eab..3f3a316ba418ff2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10396,7 +10396,8 @@ class ExtraFlags {
       Flags |= InlineAsm::Extra_MayUnwind;
     if (Call.isConvergent())
       Flags |= InlineAsm::Extra_IsConvergent;
-    Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
+    if (IA->getDialect() == InlineAsm::AD_Intel)
+      Flags |= InlineAsm::Extra_AsmDialect;
   }
 
   void update(const TargetLowering::AsmOperandInfo &OpInfo) {
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 41e5adf304d3560..86d2388147756a6 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -66,7 +66,7 @@ static bool useCompactUnwind(const Triple &T) {
 void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
   EHFrameSection = Ctx->getMachOSection(
       "__TEXT", "__eh_frame",
-      MachO::S_COALESCED | MachO::S_ATTR_NO_TOC |
+      llvm::to_underlying(MachO::S_COALESCED) | MachO::S_ATTR_NO_TOC |
           MachO::S_ATTR_STRIP_STATIC_SYMS | MachO::S_ATTR_LIVE_SUPPORT,
       SectionKind::getReadOnly());
 
@@ -160,7 +160,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
   if (ArchTy == Triple::ppc || ArchTy == Triple::ppc64) {
     TextCoalSection
       = Ctx->getMachOSection("__TEXT", "__textcoal_nt",
-                             MachO::S_COALESCED |
+                             llvm::to_underlying(MachO::S_COALESCED) |
                              MachO::S_ATTR_PURE_INSTRUCTIONS,
                              SectionKind::getText());
     ConstTextCoalSection
diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index ba6813c142266f9..25e6cab7d9fee50 100644
--- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -269,7 +269,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
 
   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
     return parseSectionSwitch("__TEXT","__symbol_stub",
-                              MachO::S_SYMBOL_STUBS |
+                              llvm::to_underlying(MachO::S_SYMBOL_STUBS) |
                               MachO::S_ATTR_PURE_INSTRUCTIONS,
                               // FIXME: Different on PPC and ARM.
                               0, 16);
@@ -277,7 +277,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
 
   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
     return parseSectionSwitch("__TEXT","__picsymbol_stub",
-                              MachO::S_SYMBOL_STUBS |
+                              llvm::to_underlying(MachO::S_SYMBOL_STUBS) |
                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
   }
 
@@ -365,13 +365,13 @@ class DarwinAsmParser : public MCAsmParserExtension {
   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
     return parseSectionSwitch("__OBJC", "__cls_refs",
                               MachO::S_ATTR_NO_DEAD_STRIP |
-                              MachO::S_LITERAL_POINTERS, 4);
+                              llvm::to_underlying(MachO::S_LITERAL_POINTERS), 4);
   }
 
   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
     return parseSectionSwitch("__OBJC", "__message_refs",
                               MachO::S_ATTR_NO_DEAD_STRIP |
-                              MachO::S_LITERAL_POINTERS, 4);
+                              llvm::to_underlying(MachO::S_LITERAL_POINTERS), 4);
   }
 
   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index 364d8f07b6df25e..eff041737b4050a 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -81,7 +81,7 @@ static MCCFIInstruction createScaledCFAInPrivateWave(const GCNSubtarget &ST,
           << uint8_t(dwarf::DW_OP_lit0 + WavefrontSizeLog2)
           << uint8_t(dwarf::DW_OP_shl)
           << uint8_t(dwarf::DW_OP_lit0 +
-                     dwarf::DW_ASPACE_LLVM_AMDGPU_private_wave)
+                     llvm::to_underlying(dwarf::DW_ASPACE_LLVM_AMDGPU_private_wave))
           << uint8_t(dwarf::DW_OP_LLVM_user)
           << uint8_t(dwarf::DW_OP_LLVM_form_aspace_address);
 
@@ -780,7 +780,7 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF,
         4, // length
         static_cast<char>(dwarf::DW_OP_lit0),
         static_cast<char>(dwarf::DW_OP_lit0 +
-                          dwarf::DW_ASPACE_LLVM_AMDGPU_private_wave),
+                          llvm::to_underlying(dwarf::DW_ASPACE_LLVM_AMDGPU_private_wave)),
         static_cast<char>(dwarf::DW_OP_LLVM_user),
         static_cast<char>(dwarf::DW_OP_LLVM_form_aspace_address)};
     static StringRef CFAEncodedInstUserOps =
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
index 129f3071a3a884e..088cebe1d53d5d5 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
@@ -628,7 +628,7 @@ struct OpRef {
     assert(!R.isValue());
     return OpRef(R.OpN & (Undef | Index | HiHalf));
   }
-  static OpRef undef(MVT Ty) { return OpRef(Undef | Ty.SimpleTy); }
+  static OpRef undef(MVT Ty) { return OpRef(Undef | llvm::to_underlying(Ty.SimpleTy)); }
 
   // Direct value.
   SDValue OpV = SDValue();
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 4581da3c7b9c30f..1895fa2eb9920c0 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -252,7 +252,7 @@ bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
         Ctx);
   }
   MCFixup Fixup =
-      MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN);
+      MCFixup::create(0, Expr, FirstLiteralRelocationKind + llvm::to_underlying(ELF::R_LARCH_ALIGN));
   F.setVarFixups({Fixup});
   F.setLinkerRelaxable();
   return true;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index 8146a15eba29573..3a77bd154ca2c9f 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -166,7 +166,7 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
       // `la.abs`.
       Fixups.push_back(
           MCFixup::create(0, MCConstantExpr::create(0, Ctx),
-                          FirstLiteralRelocationKind + ELF::R_LARCH_MARK_LA));
+                          FirstLiteralRelocationKind + llvm::to_underlying(ELF::R_LARCH_MARK_LA)));
       [[fallthrough]];
     case ELF::R_LARCH_ABS_HI20:
       FixupKind = LoongArch::fixup_loongarch_abs_hi20;
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
index 7b2d2be503d7275..0a64998a213c79a 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
@@ -157,7 +157,7 @@ void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
   MCFragment *F = LabelSym->getFragment();
   F->addFixup(
       MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
-                      FirstLiteralRelocationKind + ELF::R_PPC64_PCREL_OPT));
+                      FirstLiteralRelocationKind + llvm::to_underlying(ELF::R_PPC64_PCREL_OPT)));
   emitLabel(CurrentLocation, Inst.getLoc());
 }
 
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
index d686a8ea2a2281a..cd7317927411061 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
@@ -13,6 +13,8 @@
 #ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H
 #define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H
 
+#include "llvm/ADT/STLForwardCompat.h"
+
 // GCC #defines PPC on Linux but we use it as our namespace name
 #undef PPC
 
@@ -66,6 +68,14 @@ namespace PPC {
     BR_HINT_MASK     = 0X3
   };
 
+  inline unsigned operator&(Predicate P, BranchHintBit B) {
+    return llvm::to_underlying(P) & llvm::to_underlying(B);
+  }
+
+  inline unsigned operator&(BranchHintBit B, Predicate P) {
+    return P & B;
+  }
+
   /// Invert the specified predicate.  != -> ==, < -> >=.
   Predicate InvertPredicate(Predicate Opcode);
 
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 315d129aeb5fbac..9c9fb67968a7d4a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -350,7 +350,7 @@ bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
   Size = F.getAlignment().value() - MinNopLen;
   auto *Expr = MCConstantExpr::create(Size, getContext());
   MCFixup Fixup =
-      MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_RISCV_ALIGN);
+      MCFixup::create(0, Expr, FirstLiteralRelocationKind + llvm::to_underlying(ELF::R_RISCV_ALIGN));
   F.setVarFixups({Fixup});
   F.setLinkerRelaxable();
   return true;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
index 383c96e8cca7346..bd0bcabb0e2399c 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
@@ -172,7 +172,7 @@ uint64_t SystemZMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNum,
     unsigned MIBitSize = MCII.get(MI.getOpcode()).getSize() * 8;
     uint32_t RawBitOffset = getOperandBitOffset(MI, OpNum, STI);
     unsigned OpBitSize =
-        SystemZ::MCFixupKindInfos[Kind - FirstTargetFixupKind].TargetSize;
+        SystemZ::MCFixupKindInfos[llvm::to_underlying(Kind) - FirstTargetFixupKind].TargetSize;
     uint32_t BitOffset = MIBitSize - RawBitOffset - OpBitSize;
     addFixup(Fixups, BitOffset >> 3, MO.getExpr(), Kind);
     return 0;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index ab535c81dbf42c8..8f2374426b8061b 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -542,7 +542,7 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
       assert(ImmOffset == 0);
 
       if (Size == 8) {
-        FixupKind = FirstLiteralRelocationKind + ELF::R_X86_64_GOTPC64;
+        FixupKind = FirstLiteralRelocationKind + llvm::to_underlying(ELF::R_X86_64_GOTPC64);
       } else {
         assert(Size == 4);
         FixupKind = X86::reloc_global_offset_table;



More information about the llvm-commits mailing list