Author: Koakuma
Date: 2026-01-21T08:06:58Z
New Revision: 16fcbfb51be736dbb8059ed6c79100d9f1ea135d

URL: 
https://github.com/llvm/llvm-project/commit/16fcbfb51be736dbb8059ed6c79100d9f1ea135d
DIFF: 
https://github.com/llvm/llvm-project/commit/16fcbfb51be736dbb8059ed6c79100d9f1ea135d.diff

LOG: [SPARC] Prevent RESTORE from sourcing from %o7 in call delay slots 
(#172593)

Combining instructions that reads from %o7 with a RESTORE in call delay
slots will result in a RESTORE instruction that reads from %o7, which
has been overwritten by the call instruction, resulting in junk values
being produced.

This should fix the issue with `test-suite::lencod.test`.

(cherry picked from commit ab4adedd1c1ad9f30637291dfe94f9f0519ea2f5)

Added: 
    

Modified: 
    llvm/lib/Target/Sparc/DelaySlotFiller.cpp
    llvm/lib/Target/Sparc/SparcInstrInfo.td
    llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp 
b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
index 024030d196ee3..7d7aa20869c20 100644
--- a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
+++ b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
@@ -303,15 +303,20 @@ void 
Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,
                                 SmallSet<unsigned, 32>& RegDefs,
                                 SmallSet<unsigned, 32>& RegUses)
 {
-  // Call defines o7, which is visible to the instruction in delay slot.
-  RegDefs.insert(SP::O7);
-
+  // Regular calls define o7, which is visible to the instruction in delay 
slot.
+  // On the other hand, tail calls preserve it.
   switch(MI->getOpcode()) {
   default: llvm_unreachable("Unknown opcode.");
   case SP::CALL:
+    RegDefs.insert(SP::O7);
+    break;
+  case SP::TAIL_CALL:
     break;
   case SP::CALLrr:
   case SP::CALLri:
+    RegDefs.insert(SP::O7);
+    [[fallthrough]];
+  case SP::TAIL_CALLri:
     assert(MI->getNumOperands() >= 2);
     const MachineOperand &Reg = MI->getOperand(0);
     assert(Reg.isReg() && "CALL first operand is not a register.");
@@ -390,19 +395,33 @@ bool Filler::needsUnimp(MachineBasicBlock::iterator I, 
unsigned &StructSize)
   return true;
 }
 
-static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI,
+static bool combineRestoreADD(MachineBasicBlock &MBB,
+                              MachineBasicBlock::iterator RestoreMI,
                               MachineBasicBlock::iterator AddMI,
-                              const TargetInstrInfo *TII)
-{
+                              const TargetInstrInfo *TII) {
   // Before:  add  <op0>, <op1>, %i[0-7]
   //          restore %g0, %g0, %i[0-7]
   //
   // After :  restore <op0>, <op1>, %o[0-7]
 
+  const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
   Register reg = AddMI->getOperand(0).getReg();
   if (reg < SP::I0 || reg > SP::I7)
     return false;
 
+  // Check whether it uses %o7 as its source and the corresponding branch
+  // instruction is a call.
+  MachineBasicBlock::iterator LastInst = MBB.getFirstTerminator();
+  bool IsCall = LastInst != MBB.end() && LastInst->isCall();
+
+  if (IsCall && AddMI->getOpcode() == SP::ADDrr &&
+      AddMI->readsRegister(SP::O7, TRI))
+    return false;
+
+  if (IsCall && AddMI->getOpcode() == SP::ADDri &&
+      AddMI->readsRegister(SP::O7, TRI))
+    return false;
+
   // Erase RESTORE.
   RestoreMI->eraseFromParent();
 
@@ -417,16 +436,17 @@ static bool combineRestoreADD(MachineBasicBlock::iterator 
RestoreMI,
   return true;
 }
 
-static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI,
+static bool combineRestoreOR(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator RestoreMI,
                              MachineBasicBlock::iterator OrMI,
-                             const TargetInstrInfo *TII)
-{
+                             const TargetInstrInfo *TII) {
   // Before:  or  <op0>, <op1>, %i[0-7]
   //          restore %g0, %g0, %i[0-7]
   //    and <op0> or <op1> is zero,
   //
   // After :  restore <op0>, <op1>, %o[0-7]
 
+  const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
   Register reg = OrMI->getOperand(0).getReg();
   if (reg < SP::I0 || reg > SP::I7)
     return false;
@@ -442,6 +462,15 @@ static bool combineRestoreOR(MachineBasicBlock::iterator 
RestoreMI,
       && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
     return false;
 
+  // Check whether it uses %o7 as its source and the corresponding branch
+  // instruction is a call.
+  MachineBasicBlock::iterator LastInst = MBB.getFirstTerminator();
+  bool IsCall = LastInst != MBB.end() && LastInst->isCall();
+
+  if (IsCall && OrMI->getOpcode() == SP::ORrr &&
+      OrMI->readsRegister(SP::O7, TRI))
+    return false;
+
   // Erase RESTORE.
   RestoreMI->eraseFromParent();
 
@@ -520,9 +549,11 @@ bool 
Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
   switch (PrevInst->getOpcode()) {
   default: break;
   case SP::ADDrr:
-  case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); break;
+  case SP::ADDri:
+    return combineRestoreADD(MBB, MBBI, PrevInst, TII);
   case SP::ORrr:
-  case SP::ORri:  return combineRestoreOR(MBBI, PrevInst, TII); break;
+  case SP::ORri:
+    return combineRestoreOR(MBB, MBBI, PrevInst, TII);
   case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break;
   }
   // It cannot combine with the previous instruction.

diff  --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td 
b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 65d37599e6a8e..8717b9347210c 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -1095,7 +1095,7 @@ def CPBCONDA : CPBranchSPA<(ins brtarget:$imm22, 
CCOp:$cond),
 
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
-let Uses = [O6],
+let Uses = [O6], Defs = [O7],
     hasDelaySlot = 1, isCall = 1 in {
   def CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops),
                     "call $disp",
@@ -1589,8 +1589,8 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in
 
//===----------------------------------------------------------------------===//
 // Instructions for tail calls.
 
//===----------------------------------------------------------------------===//
-let isCodeGenOnly = 1, isReturn = 1,  hasDelaySlot = 1,
-    isTerminator = 1, isBarrier = 1 in {
+let isCodeGenOnly = 1, isReturn = 1, hasDelaySlot = 1, isTerminator = 1,
+    isBarrier = 1, isCall = 1 in {
   def TAIL_CALL : InstSP<(outs), (ins calltarget:$disp, variable_ops),
                          "call $disp",
                          [(tailcall tglobaladdr:$disp)]> {
@@ -1603,8 +1603,8 @@ let isCodeGenOnly = 1, isReturn = 1,  hasDelaySlot = 1,
 def : Pat<(tailcall (iPTR texternalsym:$dst)),
           (TAIL_CALL texternalsym:$dst)>;
 
-let isCodeGenOnly = 1, isReturn = 1,  hasDelaySlot = 1,  isTerminator = 1,
-    isBarrier = 1, rd = 0 in {
+let isCodeGenOnly = 1, isReturn = 1, hasDelaySlot = 1, isTerminator = 1,
+    isBarrier = 1, isCall = 1, rd = 0 in {
   def TAIL_CALLri : F3_2<2, 0b111000,
                          (outs), (ins (MEMri $rs1, $simm13):$addr, 
variable_ops),
                          "jmp $addr",

diff  --git a/llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll 
b/llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
index 4a15e35e718fd..9863e9f743540 100644
--- a/llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
+++ b/llvm/test/CodeGen/SPARC/2011-01-19-DelaySlot.ll
@@ -246,10 +246,100 @@ entry:
   %1 = add nsw i32 %i0, 3
   tail call void asm sideeffect "", 
"r,r,~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o6},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7}"(i32
 %0, i32 %1)
   %2 = add nsw i32 %0, %1
+  %3 = call i32 @bar(i32 %2)
+  ret i32 %3
+}
+
+define i32 @prevent_o7_in_restore_add_in_call_delay_slot(i32 %i0) nounwind {
+; CHECK-LABEL: prevent_o7_in_restore_add_in_call_delay_slot:
+; CHECK:       ! %bb.0: ! %entry
+; CHECK-NEXT:    save %sp, -96, %sp
+; CHECK-NEXT:    add %i0, 2, %o5
+; CHECK-NEXT:    add %i0, 3, %o7
+; CHECK-NEXT:    !APP
+; CHECK-NEXT:    !NO_APP
+; CHECK-NEXT:    add %o5, %o7, %i0
+; CHECK-NEXT:    call bar
+; CHECK-NEXT:    restore
+;
+; UNOPT-LABEL: prevent_o7_in_restore_add_in_call_delay_slot:
+; UNOPT:       ! %bb.0: ! %entry
+; UNOPT-NEXT:    save %sp, -104, %sp
+; UNOPT-NEXT:    add %i0, 2, %o5
+; UNOPT-NEXT:    st %o5, [%fp+-4] ! 4-byte Folded Spill
+; UNOPT-NEXT:    add %i0, 3, %o7
+; UNOPT-NEXT:    st %o7, [%fp+-8] ! 4-byte Folded Spill
+; UNOPT-NEXT:    !APP
+; UNOPT-NEXT:    !NO_APP
+; UNOPT-NEXT:    ld [%fp+-8], %i1 ! 4-byte Folded Reload
+; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
+; UNOPT-NEXT:    call bar
+; UNOPT-NEXT:    restore %i0, %i1, %o0
+entry:
+  %0 = add nsw i32 %i0, 2
+  %1 = add nsw i32 %i0, 3
+  tail call void asm sideeffect "", 
"r,r,~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o6},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7}"(i32
 %0, i32 %1)
+  %2 = add nsw i32 %0, %1
+  %3 = tail call i32 @bar(i32 %2)
+  ret i32 %3
+}
+
+define i32 @prevent_o7_in_restore_add_ri_in_call_delay_slot(i32 %i0, i32 %i1) 
nounwind {
+; CHECK-LABEL: prevent_o7_in_restore_add_ri_in_call_delay_slot:
+; CHECK:       ! %bb.0: ! %entry
+; CHECK-NEXT:    save %sp, -96, %sp
+; CHECK-NEXT:    add %i0, %i1, %o7
+; CHECK-NEXT:    !APP
+; CHECK-NEXT:    !NO_APP
+; CHECK-NEXT:    add %o7, 1, %i0
+; CHECK-NEXT:    call bar
+; CHECK-NEXT:    restore
+;
+; UNOPT-LABEL: prevent_o7_in_restore_add_ri_in_call_delay_slot:
+; UNOPT:       ! %bb.0: ! %entry
+; UNOPT-NEXT:    save %sp, -96, %sp
+; UNOPT-NEXT:    add %i0, %i1, %o7
+; UNOPT-NEXT:    st %o7, [%fp+-4] ! 4-byte Folded Spill
+; UNOPT-NEXT:    !APP
+; UNOPT-NEXT:    !NO_APP
+; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
+; UNOPT-NEXT:    call bar
+; UNOPT-NEXT:    restore %i0, 1, %o0
+entry:
+  %0 = add nsw i32 %i0, %i1
+  tail call void asm sideeffect "", 
"r,~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7}"(i32
 %0)
+  %2 = add nsw i32 %0, 1
   %3 = tail call i32 @bar(i32 %2)
   ret i32 %3
 }
 
+define i32 @prevent_o7_in_restore_or_in_call_delay_slot(i32 %i0) nounwind {
+; CHECK-LABEL: prevent_o7_in_restore_or_in_call_delay_slot:
+; CHECK:       ! %bb.0: ! %entry
+; CHECK-NEXT:    save %sp, -96, %sp
+; CHECK-NEXT:    add %i0, 2, %o7
+; CHECK-NEXT:    !APP
+; CHECK-NEXT:    !NO_APP
+; CHECK-NEXT:    mov %o7, %i0
+; CHECK-NEXT:    call bar
+; CHECK-NEXT:    restore
+;
+; UNOPT-LABEL: prevent_o7_in_restore_or_in_call_delay_slot:
+; UNOPT:       ! %bb.0: ! %entry
+; UNOPT-NEXT:    save %sp, -96, %sp
+; UNOPT-NEXT:    add %i0, 2, %o7
+; UNOPT-NEXT:    st %o7, [%fp+-4] ! 4-byte Folded Spill
+; UNOPT-NEXT:    !APP
+; UNOPT-NEXT:    !NO_APP
+; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
+; UNOPT-NEXT:    call bar
+; UNOPT-NEXT:    restore
+entry:
+  %0 = add nsw i32 %i0, 2
+  tail call void asm sideeffect "", 
"r,~{l0},~{l1},~{l2},~{l3},~{l4},~{l5},~{l6},~{l7},~{i0},~{i1},~{i2},~{i3},~{i4},~{i5},~{i6},~{i7},~{o0},~{o1},~{o2},~{o3},~{o4},~{o5},~{o6},~{g1},~{g2},~{g3},~{g4},~{g5},~{g6},~{g7}"(i32
 %0)
+  %1 = tail call i32 @bar(i32 %0)
+  ret i32 %1
+}
 
 declare i32 @func(ptr)
 
@@ -379,12 +469,12 @@ define i32 @restore_sethi(i32 %a) {
 ; CHECK-NEXT:    call bar
 ; CHECK-NEXT:    mov %i0, %o0
 ; CHECK-NEXT:    cmp %o0, 0
-; CHECK-NEXT:    bne .LBB10_2
+; CHECK-NEXT:    bne .LBB13_2
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:  ! %bb.1: ! %entry
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %g0, %g0, %o0
-; CHECK-NEXT:  .LBB10_2:
+; CHECK-NEXT:  .LBB13_2:
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %g0, 3072, %o0
 ;
@@ -401,12 +491,12 @@ define i32 @restore_sethi(i32 %a) {
 ; UNOPT-NEXT:    st %i0, [%fp+-8] ! 4-byte Folded Spill
 ; UNOPT-NEXT:    sethi 3, %i0
 ; UNOPT-NEXT:    cmp %o0, 0
-; UNOPT-NEXT:    bne .LBB10_2
+; UNOPT-NEXT:    bne .LBB13_2
 ; UNOPT-NEXT:    st %i0, [%fp+-4]
 ; UNOPT-NEXT:  ! %bb.1: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    st %i0, [%fp+-4] ! 4-byte Folded Spill
-; UNOPT-NEXT:  .LBB10_2: ! %entry
+; UNOPT-NEXT:  .LBB13_2: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    ret
 ; UNOPT-NEXT:    restore
@@ -428,12 +518,12 @@ define i32 @restore_sethi_3bit(i32 %a) {
 ; CHECK-NEXT:    call bar
 ; CHECK-NEXT:    mov %i0, %o0
 ; CHECK-NEXT:    cmp %o0, 0
-; CHECK-NEXT:    bne .LBB11_2
+; CHECK-NEXT:    bne .LBB14_2
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:  ! %bb.1: ! %entry
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %g0, %g0, %o0
-; CHECK-NEXT:  .LBB11_2:
+; CHECK-NEXT:  .LBB14_2:
 ; CHECK-NEXT:    sethi 6, %i0
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore
@@ -451,12 +541,12 @@ define i32 @restore_sethi_3bit(i32 %a) {
 ; UNOPT-NEXT:    st %i0, [%fp+-8] ! 4-byte Folded Spill
 ; UNOPT-NEXT:    sethi 6, %i0
 ; UNOPT-NEXT:    cmp %o0, 0
-; UNOPT-NEXT:    bne .LBB11_2
+; UNOPT-NEXT:    bne .LBB14_2
 ; UNOPT-NEXT:    st %i0, [%fp+-4]
 ; UNOPT-NEXT:  ! %bb.1: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    st %i0, [%fp+-4] ! 4-byte Folded Spill
-; UNOPT-NEXT:  .LBB11_2: ! %entry
+; UNOPT-NEXT:  .LBB14_2: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    ret
 ; UNOPT-NEXT:    restore
@@ -478,12 +568,12 @@ define i32 @restore_sethi_large(i32 %a) {
 ; CHECK-NEXT:    call bar
 ; CHECK-NEXT:    mov %i0, %o0
 ; CHECK-NEXT:    cmp %o0, 0
-; CHECK-NEXT:    bne .LBB12_2
+; CHECK-NEXT:    bne .LBB15_2
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:  ! %bb.1: ! %entry
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %g0, %g0, %o0
-; CHECK-NEXT:  .LBB12_2:
+; CHECK-NEXT:  .LBB15_2:
 ; CHECK-NEXT:    sethi 4000, %i0
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore
@@ -501,12 +591,12 @@ define i32 @restore_sethi_large(i32 %a) {
 ; UNOPT-NEXT:    st %i0, [%fp+-8] ! 4-byte Folded Spill
 ; UNOPT-NEXT:    sethi 4000, %i0
 ; UNOPT-NEXT:    cmp %o0, 0
-; UNOPT-NEXT:    bne .LBB12_2
+; UNOPT-NEXT:    bne .LBB15_2
 ; UNOPT-NEXT:    st %i0, [%fp+-4]
 ; UNOPT-NEXT:  ! %bb.1: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    st %i0, [%fp+-4] ! 4-byte Folded Spill
-; UNOPT-NEXT:  .LBB12_2: ! %entry
+; UNOPT-NEXT:  .LBB15_2: ! %entry
 ; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    ret
 ; UNOPT-NEXT:    restore
@@ -525,14 +615,14 @@ define i32 @test_generic_inst(i32 %arg) #0 {
 ; CHECK-NEXT:    mov %i0, %o0
 ; CHECK-NEXT:    andcc %o0, 1, %g0
 ; CHECK-NEXT:    ! fake_use: $i0
-; CHECK-NEXT:    bne .LBB13_2
+; CHECK-NEXT:    bne .LBB16_2
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:  ! %bb.1: ! %true
 ; CHECK-NEXT:    call bar
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %g0, %o0, %o0
-; CHECK-NEXT:  .LBB13_2: ! %false
+; CHECK-NEXT:  .LBB16_2: ! %false
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    restore %o0, 1, %o0
 ;
@@ -547,21 +637,21 @@ define i32 @test_generic_inst(i32 %arg) #0 {
 ; UNOPT-NEXT:    and %o0, 1, %i0
 ; UNOPT-NEXT:    ! fake_use: $i1
 ; UNOPT-NEXT:    cmp %i0, 0
-; UNOPT-NEXT:    bne .LBB13_2
+; UNOPT-NEXT:    bne .LBB16_2
 ; UNOPT-NEXT:    nop
-; UNOPT-NEXT:    ba .LBB13_1
+; UNOPT-NEXT:    ba .LBB16_1
 ; UNOPT-NEXT:    nop
-; UNOPT-NEXT:  .LBB13_1: ! %true
+; UNOPT-NEXT:  .LBB16_1: ! %true
 ; UNOPT-NEXT:    call bar
 ; UNOPT-NEXT:    ld [%fp+-4], %o0
-; UNOPT-NEXT:    ba .LBB13_3
+; UNOPT-NEXT:    ba .LBB16_3
 ; UNOPT-NEXT:    st %o0, [%fp+-8]
-; UNOPT-NEXT:  .LBB13_2: ! %false
+; UNOPT-NEXT:  .LBB16_2: ! %false
 ; UNOPT-NEXT:    ld [%fp+-4], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    add %i0, 1, %i0
-; UNOPT-NEXT:    ba .LBB13_3
+; UNOPT-NEXT:    ba .LBB16_3
 ; UNOPT-NEXT:    st %i0, [%fp+-8]
-; UNOPT-NEXT:  .LBB13_3: ! %cont
+; UNOPT-NEXT:  .LBB16_3: ! %cont
 ; UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
 ; UNOPT-NEXT:    ret
 ; UNOPT-NEXT:    restore


        
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to