Author: Shoreshen Date: 2025-04-01T18:26:45+08:00 New Revision: fd6b5306b6dd21cef8290eb623aeb42e735c6f06
URL: https://github.com/llvm/llvm-project/commit/fd6b5306b6dd21cef8290eb623aeb42e735c6f06 DIFF: https://github.com/llvm/llvm-project/commit/fd6b5306b6dd21cef8290eb623aeb42e735c6f06.diff LOG: Merge branch 'main' into revert-133880-revert-130577-narrow-math-for-and-operand Added: llvm/include/llvm/CodeGen/XRayInstrumentation.h llvm/test/CodeGen/AArch64/early-ifcvt-on-double-killed-reg.mir llvm/test/CodeGen/Hexagon/early-if-predicator-reg-killed-everywhere.mir Modified: llvm/include/llvm/InitializePasses.h llvm/include/llvm/Passes/CodeGenPassBuilder.h llvm/include/llvm/Passes/MachinePassRegistry.def llvm/lib/CodeGen/CodeGen.cpp llvm/lib/CodeGen/EarlyIfConversion.cpp llvm/lib/CodeGen/XRayInstrumentation.cpp llvm/lib/Passes/PassBuilder.cpp llvm/test/CodeGen/X86/xray-empty-firstmbb.mir llvm/test/CodeGen/X86/xray-multiplerets-in-blocks.mir Removed: ################################################################################ diff --git a/llvm/include/llvm/CodeGen/XRayInstrumentation.h b/llvm/include/llvm/CodeGen/XRayInstrumentation.h new file mode 100644 index 0000000000000..cc65d61627fc0 --- /dev/null +++ b/llvm/include/llvm/CodeGen/XRayInstrumentation.h @@ -0,0 +1,25 @@ +//===- llvm/CodeGen/XRayInstrumentation.h -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_XRAYINSTRUMENTATION_H +#define LLVM_CODEGEN_XRAYINSTRUMENTATION_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { + +class XRayInstrumentationPass : public PassInfoMixin<XRayInstrumentationPass> { +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); + static bool isRequired() { return true; } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_XRAYINSTRUMENTATION_H diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index cc7bf245c37f5..fb27867176788 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -322,7 +322,7 @@ void initializeVirtRegRewriterPass(PassRegistry &); void initializeWasmEHPreparePass(PassRegistry &); void initializeWinEHPreparePass(PassRegistry &); void initializeWriteBitcodePassPass(PassRegistry &); -void initializeXRayInstrumentationPass(PassRegistry &); +void initializeXRayInstrumentationLegacyPass(PassRegistry &); } // end namespace llvm diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h index bdb81cf77cfd1..25ca982916ff8 100644 --- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h +++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h @@ -90,6 +90,7 @@ #include "llvm/CodeGen/UnreachableBlockElim.h" #include "llvm/CodeGen/WasmEHPrepare.h" #include "llvm/CodeGen/WinEHPrepare.h" +#include "llvm/CodeGen/XRayInstrumentation.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/IRPrinter/IRPrintingPasses.h" diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def index 73c4d34faa5a3..3e9e788662900 100644 --- a/llvm/include/llvm/Passes/MachinePassRegistry.def +++ b/llvm/include/llvm/Passes/MachinePassRegistry.def @@ -190,6 +190,7 @@ MACHINE_FUNCTION_PASS("trigger-verifier-error", TriggerVerifierErrorPass()) MACHINE_FUNCTION_PASS("two-address-instruction", TwoAddressInstructionPass()) MACHINE_FUNCTION_PASS("verify", MachineVerifierPass()) MACHINE_FUNCTION_PASS("verify<machine-trace-metrics>", MachineTraceMetricsVerifierPass()) +MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass()) #undef MACHINE_FUNCTION_PASS #ifndef MACHINE_FUNCTION_PASS_WITH_PARAMS @@ -315,5 +316,4 @@ DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass) DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass) DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass) DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass) -DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass) #undef DUMMY_MACHINE_FUNCTION_PASS diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 771e45ce71595..b1c26307b80fc 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -145,5 +145,5 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeVirtRegRewriterPass(Registry); initializeWasmEHPreparePass(Registry); initializeWinEHPreparePass(Registry); - initializeXRayInstrumentationPass(Registry); + initializeXRayInstrumentationLegacyPass(Registry); } diff --git a/llvm/lib/CodeGen/EarlyIfConversion.cpp b/llvm/lib/CodeGen/EarlyIfConversion.cpp index 24c6dafc60459..da0987c3b50bb 100644 --- a/llvm/lib/CodeGen/EarlyIfConversion.cpp +++ b/llvm/lib/CodeGen/EarlyIfConversion.cpp @@ -17,6 +17,7 @@ #include "llvm/CodeGen/EarlyIfConversion.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SparseSet.h" @@ -31,6 +32,7 @@ #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineTraceMetrics.h" +#include "llvm/CodeGen/Register.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -163,6 +165,11 @@ class SSAIfConv { /// Insert selects and rewrite PHI operands to use them. void rewritePHIOperands(); + /// If virtual register has "killed" flag in TBB and FBB basic blocks, remove + /// the flag in TBB instruction. + void clearRepeatedKillFlagsFromTBB(MachineBasicBlock *TBB, + MachineBasicBlock *FBB); + public: /// init - Initialize per-function data structures. void init(MachineFunction &MF) { @@ -675,6 +682,31 @@ void SSAIfConv::rewritePHIOperands() { } } +void SSAIfConv::clearRepeatedKillFlagsFromTBB(MachineBasicBlock *TBB, + MachineBasicBlock *FBB) { + assert(TBB != FBB); + + // Collect virtual registers killed in FBB. + SmallDenseSet<Register> FBBKilledRegs; + for (MachineInstr &MI : FBB->instrs()) { + for (MachineOperand &MO : MI.operands()) { + if (MO.isReg() && MO.isKill() && MO.getReg().isVirtual()) + FBBKilledRegs.insert(MO.getReg()); + } + } + + if (FBBKilledRegs.empty()) + return; + + // Find the same killed registers in TBB and clear kill flags for them. + for (MachineInstr &MI : TBB->instrs()) { + for (MachineOperand &MO : MI.operands()) { + if (MO.isReg() && MO.isKill() && FBBKilledRegs.contains(MO.getReg())) + MO.setIsKill(false); + } + } +} + /// convertIf - Execute the if conversion after canConvertIf has determined the /// feasibility. /// @@ -690,6 +722,13 @@ void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks, else ++NumDiamondsConv; + // If both blocks are going to be merged into Head, remove "killed" flag in + // TBB for registers, which are killed in TBB and FBB. Otherwise, register + // will be killed twice in Head after splice. Register killed twice is an + // incorrect MIR. + if (TBB != Tail && FBB != Tail) + clearRepeatedKillFlagsFromTBB(TBB, FBB); + // Move all instructions into Head, except for the terminators. if (TBB != Tail) { if (Predicate) diff --git a/llvm/lib/CodeGen/XRayInstrumentation.cpp b/llvm/lib/CodeGen/XRayInstrumentation.cpp index 0873d9956356e..dbdb81d1e6b33 100644 --- a/llvm/lib/CodeGen/XRayInstrumentation.cpp +++ b/llvm/lib/CodeGen/XRayInstrumentation.cpp @@ -13,14 +13,17 @@ // //===---------------------------------------------------------------------===// +#include "llvm/CodeGen/XRayInstrumentation.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Attributes.h" @@ -44,11 +47,11 @@ struct InstrumentationOptions { bool HandleAllReturns; }; -struct XRayInstrumentation : public MachineFunctionPass { +struct XRayInstrumentationLegacy : public MachineFunctionPass { static char ID; - XRayInstrumentation() : MachineFunctionPass(ID) { - initializeXRayInstrumentationPass(*PassRegistry::getPassRegistry()); + XRayInstrumentationLegacy() : MachineFunctionPass(ID) { + initializeXRayInstrumentationLegacyPass(*PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -59,6 +62,27 @@ struct XRayInstrumentation : public MachineFunctionPass { } bool runOnMachineFunction(MachineFunction &MF) override; +}; + +struct XRayInstrumentation { + XRayInstrumentation(MachineDominatorTree *MDT, MachineLoopInfo *MLI) + : MDT(MDT), MLI(MLI) {} + + bool run(MachineFunction &MF); + + // Methods for use in the NPM and legacy passes, can be removed once migration + // is complete. + static bool alwaysInstrument(Function &F) { + auto InstrAttr = F.getFnAttribute("function-instrument"); + return InstrAttr.isStringAttribute() && + InstrAttr.getValueAsString() == "xray-always"; + } + + static bool needMDTAndMLIAnalyses(Function &F) { + auto IgnoreLoopsAttr = F.getFnAttribute("xray-ignore-loops"); + auto AlwaysInstrument = XRayInstrumentation::alwaysInstrument(F); + return !AlwaysInstrument && !IgnoreLoopsAttr.isValid(); + } private: // Replace the original RET instruction with the exit sled code ("patchable @@ -82,6 +106,9 @@ struct XRayInstrumentation : public MachineFunctionPass { void prependRetWithPatchableExit(MachineFunction &MF, const TargetInstrInfo *TII, InstrumentationOptions); + + MachineDominatorTree *MDT; + MachineLoopInfo *MLI; }; } // end anonymous namespace @@ -143,11 +170,42 @@ void XRayInstrumentation::prependRetWithPatchableExit( } } -bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { +PreservedAnalyses +XRayInstrumentationPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + MachineDominatorTree *MDT = nullptr; + MachineLoopInfo *MLI = nullptr; + + if (XRayInstrumentation::needMDTAndMLIAnalyses(MF.getFunction())) { + MDT = MFAM.getCachedResult<MachineDominatorTreeAnalysis>(MF); + MLI = MFAM.getCachedResult<MachineLoopAnalysis>(MF); + } + + if (!XRayInstrumentation(MDT, MLI).run(MF)) + return PreservedAnalyses::all(); + + auto PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet<CFGAnalyses>(); + return PA; +} + +bool XRayInstrumentationLegacy::runOnMachineFunction(MachineFunction &MF) { + MachineDominatorTree *MDT = nullptr; + MachineLoopInfo *MLI = nullptr; + if (XRayInstrumentation::needMDTAndMLIAnalyses(MF.getFunction())) { + auto *MDTWrapper = + getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>(); + MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; + auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>(); + MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; + } + return XRayInstrumentation(MDT, MLI).run(MF); +} + +bool XRayInstrumentation::run(MachineFunction &MF) { auto &F = MF.getFunction(); auto InstrAttr = F.getFnAttribute("function-instrument"); - bool AlwaysInstrument = InstrAttr.isStringAttribute() && - InstrAttr.getValueAsString() == "xray-always"; + bool AlwaysInstrument = alwaysInstrument(F); bool NeverInstrument = InstrAttr.isStringAttribute() && InstrAttr.getValueAsString() == "xray-never"; if (NeverInstrument && !AlwaysInstrument) @@ -171,9 +229,6 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { if (!IgnoreLoops) { // Get MachineDominatorTree or compute it on the fly if it's unavailable - auto *MDTWrapper = - getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>(); - auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; MachineDominatorTree ComputedMDT; if (!MDT) { ComputedMDT.recalculate(MF); @@ -181,8 +236,6 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { } // Get MachineLoopInfo or compute it on the fly if it's unavailable - auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>(); - auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; MachineLoopInfo ComputedMLI; if (!MLI) { ComputedMLI.analyze(*MDT); @@ -272,10 +325,10 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { return true; } -char XRayInstrumentation::ID = 0; -char &llvm::XRayInstrumentationID = XRayInstrumentation::ID; -INITIALIZE_PASS_BEGIN(XRayInstrumentation, "xray-instrumentation", +char XRayInstrumentationLegacy::ID = 0; +char &llvm::XRayInstrumentationID = XRayInstrumentationLegacy::ID; +INITIALIZE_PASS_BEGIN(XRayInstrumentationLegacy, "xray-instrumentation", "Insert XRay ops", false, false) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) -INITIALIZE_PASS_END(XRayInstrumentation, "xray-instrumentation", +INITIALIZE_PASS_END(XRayInstrumentationLegacy, "xray-instrumentation", "Insert XRay ops", false, false) diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 8646c1f49ac35..536a7fcb67b5e 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -165,6 +165,7 @@ #include "llvm/CodeGen/VirtRegMap.h" #include "llvm/CodeGen/WasmEHPrepare.h" #include "llvm/CodeGen/WinEHPrepare.h" +#include "llvm/CodeGen/XRayInstrumentation.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/PassManager.h" diff --git a/llvm/test/CodeGen/AArch64/early-ifcvt-on-double-killed-reg.mir b/llvm/test/CodeGen/AArch64/early-ifcvt-on-double-killed-reg.mir new file mode 100644 index 0000000000000..27222e46b9c10 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/early-ifcvt-on-double-killed-reg.mir @@ -0,0 +1,54 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=aarch64-- -run-pass=early-ifcvt -stress-early-ifcvt %s -o - -verify-machineinstrs | FileCheck %s + +# Test that "killed" flag on the same virtual register in merged blocks is +# removed for the first spliced block and is saved for the second one. +# Otherwise, register will be killed twice in a single block in the resulting +# MIR, which is incorrect. + +--- +name: my_func +tracksRegLiveness: true +liveins: + - { reg: '$w0', virtual-reg: '%0' } +body: | + ; CHECK-LABEL: name: my_func + ; CHECK: bb.0.entry: + ; CHECK-NEXT: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32common = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x0 + ; CHECK-NEXT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri [[COPY]], 1, 0, implicit-def $nzcv + ; CHECK-NEXT: [[ADDWri:%[0-9]+]]:gpr32common = ADDWri [[COPY]], 3, 0 + ; CHECK-NEXT: [[SUBWri:%[0-9]+]]:gpr32common = SUBWri killed [[COPY]], 2, 0 + ; CHECK-NEXT: [[CSELWr:%[0-9]+]]:gpr32common = CSELWr [[ADDWri]], [[SUBWri]], 1, implicit $nzcv + ; CHECK-NEXT: $x2 = COPY [[COPY1]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 + bb.0.entry: + successors: %bb.1, %bb.2 + liveins: $w0 + + %0:gpr32common = COPY $w0 + %1:gpr64common = COPY $x0 + %2:gpr32 = SUBSWri %0, 1, 0, implicit-def $nzcv + Bcc 1, %bb.2, implicit $nzcv + B %bb.1 + + bb.1: + successors: %bb.3 + + %3:gpr32common = SUBWri killed %0, 2, 0 + B %bb.3 + + bb.2: + successors: %bb.3 + + %4:gpr32common = ADDWri killed %0, 3, 0 + B %bb.3 + + bb.3: + %5:gpr32common = PHI %3, %bb.1, %4, %bb.2 + $x2 = COPY %1 + RET_ReallyLR implicit $x2 + +... diff --git a/llvm/test/CodeGen/Hexagon/early-if-predicator-reg-killed-everywhere.mir b/llvm/test/CodeGen/Hexagon/early-if-predicator-reg-killed-everywhere.mir new file mode 100644 index 0000000000000..f189e89432dec --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/early-if-predicator-reg-killed-everywhere.mir @@ -0,0 +1,52 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=hexagon -run-pass early-if-predicator %s -o - -verify-machineinstrs | FileCheck %s + +# Test that "killed" flag on the same virtual register in merged blocks is +# removed for the first spliced block and is saved for the second one. +# Otherwise, register will be killed twice in a single block in the resulting +# MIR, which is incorrect. + +--- +name: my_func +alignment: 16 +tracksRegLiveness: true +liveins: + - { reg: '$r0', virtual-reg: '%0' } + - { reg: '$r1', virtual-reg: '%1' } +body: | + ; CHECK-LABEL: name: my_func + ; CHECK: bb.0: + ; CHECK-NEXT: liveins: $r0, $r1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:intregs = COPY $r0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:intregs = COPY $r1 + ; CHECK-NEXT: [[S2_tstbit_i:%[0-9]+]]:predregs = S2_tstbit_i [[COPY1]], 0 + ; CHECK-NEXT: S4_storeirif_io [[S2_tstbit_i]], [[COPY]], 0, 2 + ; CHECK-NEXT: S4_storeirit_io [[S2_tstbit_i]], killed [[COPY]], 0, 1 + ; CHECK-NEXT: PS_jmpret $r31, implicit-def dead $pc + bb.0: + successors: %bb.1(0x40000000), %bb.2(0x40000000) + liveins: $r0, $r1 + + %0:intregs = COPY $r0 + %1:intregs = COPY $r1 + %2:predregs = S2_tstbit_i %1, 0 + J2_jumpf %2, %bb.2, implicit-def dead $pc + J2_jump %bb.1, implicit-def dead $pc + + bb.1: + successors: %bb.3(0x80000000) + + S4_storeiri_io killed %0, 0, 1 + J2_jump %bb.3, implicit-def dead $pc + + bb.2: + successors: %bb.3(0x80000000) + + S4_storeiri_io killed %0, 0, 2 + J2_jump %bb.3, implicit-def dead $pc + + bb.3: + PS_jmpret $r31, implicit-def dead $pc + +... diff --git a/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir b/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir index df5dc7b28ec1a..cd8b04b96ba2b 100644 --- a/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir +++ b/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir @@ -1,4 +1,5 @@ # RUN: llc -run-pass=xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s +# RUN: llc -passes=xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s # # Make sure we can handle empty first basic blocks. diff --git a/llvm/test/CodeGen/X86/xray-multiplerets-in-blocks.mir b/llvm/test/CodeGen/X86/xray-multiplerets-in-blocks.mir index 60a33b95f1412..0ddd5037e4265 100644 --- a/llvm/test/CodeGen/X86/xray-multiplerets-in-blocks.mir +++ b/llvm/test/CodeGen/X86/xray-multiplerets-in-blocks.mir @@ -1,4 +1,5 @@ # RUN: llc -run-pass=xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s +# RUN: llc -passes=xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s # # Make sure we can handle multiple ret instructions in a single basic block for # XRay. _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits