https://github.com/tomtor updated 
https://github.com/llvm/llvm-project/pull/152028

>From c5206367a672d52b6761490b144e0221f8dafcf3 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Sun, 3 Aug 2025 09:15:58 +0200
Subject: [PATCH 1/9] Improve AVR loop code generation

---
 clang/lib/Basic/Targets/AVR.h                |  3 +-
 llvm/lib/Target/AVR/AVRTargetMachine.cpp     | 11 ++-
 llvm/lib/Target/AVR/AVRTargetMachine.h       |  2 +
 llvm/lib/Target/AVR/AVRTargetTransformInfo.h | 79 ++++++++++++++++++++
 4 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 llvm/lib/Target/AVR/AVRTargetTransformInfo.h

diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h
index 75c969fd59dc9..11aa844f2ce55 100644
--- a/clang/lib/Basic/Targets/AVR.h
+++ b/clang/lib/Basic/Targets/AVR.h
@@ -57,7 +57,8 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public 
TargetInfo {
     Int16Type = SignedInt;
     Char32Type = UnsignedLong;
     SigAtomicType = SignedChar;
-    resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
+    resetDataLayout(
+        "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-n16:8-a:8");
   }
 
   void getTargetDefines(const LangOptions &Opts,
diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp 
b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index b75417a0896a5..8d05005e287f4 100644
--- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -19,6 +19,7 @@
 
 #include "AVR.h"
 #include "AVRMachineFunctionInfo.h"
+#include "AVRTargetTransformInfo.h"
 #include "AVRTargetObjectFile.h"
 #include "MCTargetDesc/AVRMCTargetDesc.h"
 #include "TargetInfo/AVRTargetInfo.h"
@@ -28,7 +29,7 @@
 namespace llvm {
 
 static const char *AVRDataLayout =
-    "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8";
+    "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-n16:8-a:8";
 
 /// Processes a CPU name.
 static StringRef getCPU(StringRef CPU) {
@@ -62,7 +63,9 @@ namespace {
 class AVRPassConfig : public TargetPassConfig {
 public:
   AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)
-      : TargetPassConfig(TM, PM) {}
+      : TargetPassConfig(TM, PM) {
+    EnableLoopTermFold = true;
+  }
 
   AVRTargetMachine &getAVRTargetMachine() const {
     return getTM<AVRTargetMachine>();
@@ -107,6 +110,10 @@ const AVRSubtarget 
*AVRTargetMachine::getSubtargetImpl(const Function &) const {
   return &SubTarget;
 }
 
+TargetTransformInfo AVRTargetMachine::getTargetTransformInfo(const Function 
&F) const {
+  return TargetTransformInfo(std::make_unique<AVRTTIImpl>(this, F));
+}
+
 MachineFunctionInfo *AVRTargetMachine::createMachineFunctionInfo(
     BumpPtrAllocator &Allocator, const Function &F,
     const TargetSubtargetInfo *STI) const {
diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.h 
b/llvm/lib/Target/AVR/AVRTargetMachine.h
index 167d0076e9581..9452b3d8cd8a5 100644
--- a/llvm/lib/Target/AVR/AVRTargetMachine.h
+++ b/llvm/lib/Target/AVR/AVRTargetMachine.h
@@ -48,6 +48,8 @@ class AVRTargetMachine : public CodeGenTargetMachineImpl {
   createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
                             const TargetSubtargetInfo *STI) const override;
 
+  TargetTransformInfo getTargetTransformInfo(const Function &F) const override;
+
   bool isNoopAddrSpaceCast(unsigned SrcAs, unsigned DestAs) const override {
     // While AVR has different address spaces, they are all represented by
     // 16-bit pointers that can be freely casted between (of course, a pointer
diff --git a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h 
b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
new file mode 100644
index 0000000000000..e1abd10619823
--- /dev/null
+++ b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
@@ -0,0 +1,79 @@
+//===- AVRTargetTransformInfo.h - AVR specific TTI ---------*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file defines a TargetTransformInfoImplBase conforming object specific
+/// to the AVR target machine. It uses the target's detailed information to
+/// provide more precise answers to certain TTI queries, while letting the
+/// target independent and default TTI implementations handle the rest.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AVR_AVRTARGETTRANSFORMINFO_H
+#define LLVM_LIB_TARGET_AVR_AVRTARGETTRANSFORMINFO_H
+
+#include "AVRSubtarget.h"
+#include "AVRTargetMachine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+#include "llvm/IR/Function.h"
+#include <optional>
+
+namespace llvm {
+
+class AVRTTIImpl final : public BasicTTIImplBase<AVRTTIImpl> {
+  using BaseT = BasicTTIImplBase<AVRTTIImpl>;
+  using TTI = TargetTransformInfo;
+
+  friend BaseT;
+
+  const AVRSubtarget *ST;
+  const AVRTargetLowering *TLI;
+
+  const AVRSubtarget *getST() const { return ST; }
+  const AVRTargetLowering *getTLI() const { return TLI; }
+
+public:
+  explicit AVRTTIImpl(const AVRTargetMachine *TM, const Function &F)
+      : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
+        TLI(ST->getTargetLowering()) {}
+
+#if 0 // TODO Examine if these options result in better code generation
+  /// Return the cost of materializing an immediate for a value operand of
+  /// a store instruction.
+  InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo,
+                                  TTI::TargetCostKind CostKind) const;
+
+  InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
+                                TTI::TargetCostKind CostKind) const override;
+  InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
+                                    const APInt &Imm, Type *Ty,
+                                    TTI::TargetCostKind CostKind,
+                                    Instruction *Inst = nullptr) const 
override;
+  InstructionCost
+  getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+                      Type *Ty, TTI::TargetCostKind CostKind) const override;
+
+  InstructionCost
+  getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+                        TTI::TargetCostKind CostKind) const override;
+
+  InstructionCost getCmpSelInstrCost(
+      unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
+      TTI::TargetCostKind CostKind,
+      TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
+      TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
+      const Instruction *I = nullptr) const override;
+#endif
+
+  bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
+                     const TargetTransformInfo::LSRCost &C2) const override 
{return C1.Insns < C2.Insns;}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_AVR_AVRTARGETTRANSFORMINFO_H

>From 68222e983264aa5eb50ab4e655ab260da75ed8e2 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Mon, 4 Aug 2025 22:25:00 +0200
Subject: [PATCH 2/9] handle pre/post and complete tests

---
 llvm/lib/Target/AVR/AVRTargetTransformInfo.h | 49 ++++++++------------
 llvm/test/CodeGen/AVR/bug-143247.ll          |  4 +-
 llvm/test/CodeGen/AVR/load.ll                | 34 +++++++-------
 llvm/test/CodeGen/AVR/shift.ll               |  2 +-
 4 files changed, 39 insertions(+), 50 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h 
b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
index e1abd10619823..b877918a18151 100644
--- a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
+++ b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
@@ -33,6 +33,7 @@ class AVRTTIImpl final : public BasicTTIImplBase<AVRTTIImpl> {
 
   const AVRSubtarget *ST;
   const AVRTargetLowering *TLI;
+  const Function *currentF;
 
   const AVRSubtarget *getST() const { return ST; }
   const AVRTargetLowering *getTLI() const { return TLI; }
@@ -40,38 +41,26 @@ class AVRTTIImpl final : public 
BasicTTIImplBase<AVRTTIImpl> {
 public:
   explicit AVRTTIImpl(const AVRTargetMachine *TM, const Function &F)
       : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
-        TLI(ST->getTargetLowering()) {}
-
-#if 0 // TODO Examine if these options result in better code generation
-  /// Return the cost of materializing an immediate for a value operand of
-  /// a store instruction.
-  InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo,
-                                  TTI::TargetCostKind CostKind) const;
-
-  InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
-                                TTI::TargetCostKind CostKind) const override;
-  InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
-                                    const APInt &Imm, Type *Ty,
-                                    TTI::TargetCostKind CostKind,
-                                    Instruction *Inst = nullptr) const 
override;
-  InstructionCost
-  getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
-                      Type *Ty, TTI::TargetCostKind CostKind) const override;
-
-  InstructionCost
-  getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
-                        TTI::TargetCostKind CostKind) const override;
-
-  InstructionCost getCmpSelInstrCost(
-      unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
-      TTI::TargetCostKind CostKind,
-      TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
-      TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
-      const Instruction *I = nullptr) const override;
-#endif
+        TLI(ST->getTargetLowering()), currentF(&F) {}
 
   bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
-                     const TargetTransformInfo::LSRCost &C2) const override 
{return C1.Insns < C2.Insns;}
+                     const TargetTransformInfo::LSRCost &C2) const override {
+    // Detect %incdec.ptr because loop-reduce loses them
+    for (const BasicBlock &BB : *currentF) {
+      if (BB.getName().find("while.body") != std::string::npos) {
+        for (const Instruction &I : BB) {
+          std::string str;
+          llvm::raw_string_ostream(str) << I;
+          if (str.find("%incdec.ptr") != std::string::npos)
+            return false;
+        }
+      }
+    }
+    if (C2.Insns == ~0u)
+      return true;
+    return 2 * C1.Insns + C1.AddRecCost + C1.SetupCost + C1.NumRegs <
+           2 * C2.Insns + C2.AddRecCost + C2.SetupCost + C2.NumRegs;
+  }
 };
 
 } // end namespace llvm
diff --git a/llvm/test/CodeGen/AVR/bug-143247.ll 
b/llvm/test/CodeGen/AVR/bug-143247.ll
index 07c4c6562c950..d4493272af76d 100644
--- a/llvm/test/CodeGen/AVR/bug-143247.ll
+++ b/llvm/test/CodeGen/AVR/bug-143247.ll
@@ -8,18 +8,18 @@ define void @complex_sbi() {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    push r16
 ; CHECK-NEXT:    push r17
-; CHECK-NEXT:    ldi r24, 0
+; CHECK-NEXT:    ldi r24, 1
 ; CHECK-NEXT:    ldi r25, 0
 ; CHECK-NEXT:  .LBB0_1: ; %while.cond
 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    sbi 1, 7
-; CHECK-NEXT:    adiw r24, 1
 ; CHECK-NEXT:    movw r16, r24
 ; CHECK-NEXT:    andi r24, 15
 ; CHECK-NEXT:    andi r25, 0
 ; CHECK-NEXT:    adiw r24, 1
 ; CHECK-NEXT:    call nil
 ; CHECK-NEXT:    movw r24, r16
+; CHECK-NEXT:    adiw r24, 1
 ; CHECK-NEXT:    rjmp .LBB0_1
 entry:
   br label %while.cond
diff --git a/llvm/test/CodeGen/AVR/load.ll b/llvm/test/CodeGen/AVR/load.ll
index 5de6b48652914..e2e7844b49c02 100644
--- a/llvm/test/CodeGen/AVR/load.ll
+++ b/llvm/test/CodeGen/AVR/load.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mattr=avr6,sram < %s -mtriple=avr -verify-machineinstrs | 
FileCheck %s
+; RUN: llc -mattr=avr6,sram < %s -mtriple=avr-none -verify-machineinstrs | 
FileCheck %s
 
 define i8 @load8(ptr %x) {
 ; CHECK-LABEL: load8:
@@ -76,26 +76,26 @@ while.end:                                        ; preds = 
%while.body, %entry
   ret i8 %r.0.lcssa
 }
 
-define i16 @load16postinc(ptr %x, i16 %y) {
+define i16 @load16postinc(ptr %p, i16 %cnt) {
 ; CHECK-LABEL: load16postinc:
 ; CHECK: ld {{.*}}, {{[XYZ]}}+
 ; CHECK: ld {{.*}}, {{[XYZ]}}+
 entry:
-  %tobool2 = icmp eq i16 %y, 0
-  br i1 %tobool2, label %while.end, label %while.body
-while.body:                                       ; preds = %entry, %while.body
-  %r.05 = phi i16 [ %add, %while.body ], [ 0, %entry ]
-  %y.addr.04 = phi i16 [ %dec, %while.body ], [ %y, %entry ]
-  %x.addr.03 = phi ptr [ %incdec.ptr, %while.body ], [ %x, %entry ]
-  %dec = add nsw i16 %y.addr.04, -1
-  %incdec.ptr = getelementptr inbounds i16, ptr %x.addr.03, i16 1
-  %0 = load i16, ptr %x.addr.03
-  %add = add nsw i16 %0, %r.05
-  %tobool = icmp eq i16 %dec, 0
-  br i1 %tobool, label %while.end, label %while.body
-while.end:                                        ; preds = %while.body, %entry
-  %r.0.lcssa = phi i16 [ 0, %entry ], [ %add, %while.body ]
-  ret i16 %r.0.lcssa
+  %cmp3 = icmp sgt i16 %cnt, 0
+  br i1 %cmp3, label %for.body, label %for.cond.cleanup
+for.cond.cleanup:                                 ; preds = %for.body, %entry
+  %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ]
+  ret i16 %sum.0.lcssa
+for.body:                                         ; preds = %entry, %for.body
+  %i.06 = phi i16 [ %inc, %for.body ], [ 0, %entry ]
+  %sum.05 = phi i16 [ %add, %for.body ], [ 0, %entry ]
+  %p.addr.04 = phi ptr [ %incdec.ptr, %for.body ], [ %p, %entry ]
+  %incdec.ptr = getelementptr inbounds nuw i8, ptr %p.addr.04, i16 2
+  %0 = load i16, ptr %p.addr.04, align 1
+  %add = add nsw i16 %0, %sum.05
+  %inc = add nuw nsw i16 %i.06, 1
+  %exitcond.not = icmp eq i16 %inc, %cnt
+  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
 define i8 @load8predec(ptr %x, i8 %y) {
diff --git a/llvm/test/CodeGen/AVR/shift.ll b/llvm/test/CodeGen/AVR/shift.ll
index 9836f93527b3c..1bd9b45999d7b 100644
--- a/llvm/test/CodeGen/AVR/shift.ll
+++ b/llvm/test/CodeGen/AVR/shift.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=avr -mtriple=avr -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -mtriple=avr-none -verify-machineinstrs | FileCheck %s
 
 ; Optimize for speed.
 define i8 @shift_i8_i8_speed(i8 %a, i8 %b) {

>From 38ca2245d0747deb8752f8495187e54cfefc8a8d Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Mon, 4 Aug 2025 22:39:46 +0200
Subject: [PATCH 3/9] formatting

---
 llvm/lib/Target/AVR/AVRTargetMachine.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp 
b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index 8d05005e287f4..02212d2151f4c 100644
--- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -19,8 +19,8 @@
 
 #include "AVR.h"
 #include "AVRMachineFunctionInfo.h"
-#include "AVRTargetTransformInfo.h"
 #include "AVRTargetObjectFile.h"
+#include "AVRTargetTransformInfo.h"
 #include "MCTargetDesc/AVRMCTargetDesc.h"
 #include "TargetInfo/AVRTargetInfo.h"
 
@@ -110,7 +110,8 @@ const AVRSubtarget 
*AVRTargetMachine::getSubtargetImpl(const Function &) const {
   return &SubTarget;
 }
 
-TargetTransformInfo AVRTargetMachine::getTargetTransformInfo(const Function 
&F) const {
+TargetTransformInfo
+AVRTargetMachine::getTargetTransformInfo(const Function &F) const {
   return TargetTransformInfo(std::make_unique<AVRTTIImpl>(this, F));
 }
 

>From 3355cccc20d4293cb2b93b569b306309dbde1c04 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Tue, 5 Aug 2025 09:56:24 +0200
Subject: [PATCH 4/9] cleanup code and tests

---
 llvm/lib/Target/AVR/AVRTargetTransformInfo.h | 14 +-------------
 llvm/test/CodeGen/AVR/load.ll                |  6 +++---
 llvm/test/CodeGen/AVR/store.ll               |  6 +++---
 3 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h 
b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
index b877918a18151..77c2a6153f7d5 100644
--- a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
+++ b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
@@ -33,7 +33,6 @@ class AVRTTIImpl final : public BasicTTIImplBase<AVRTTIImpl> {
 
   const AVRSubtarget *ST;
   const AVRTargetLowering *TLI;
-  const Function *currentF;
 
   const AVRSubtarget *getST() const { return ST; }
   const AVRTargetLowering *getTLI() const { return TLI; }
@@ -41,21 +40,10 @@ class AVRTTIImpl final : public 
BasicTTIImplBase<AVRTTIImpl> {
 public:
   explicit AVRTTIImpl(const AVRTargetMachine *TM, const Function &F)
       : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
-        TLI(ST->getTargetLowering()), currentF(&F) {}
+        TLI(ST->getTargetLowering()) {}
 
   bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
                      const TargetTransformInfo::LSRCost &C2) const override {
-    // Detect %incdec.ptr because loop-reduce loses them
-    for (const BasicBlock &BB : *currentF) {
-      if (BB.getName().find("while.body") != std::string::npos) {
-        for (const Instruction &I : BB) {
-          std::string str;
-          llvm::raw_string_ostream(str) << I;
-          if (str.find("%incdec.ptr") != std::string::npos)
-            return false;
-        }
-      }
-    }
     if (C2.Insns == ~0u)
       return true;
     return 2 * C1.Insns + C1.AddRecCost + C1.SetupCost + C1.NumRegs <
diff --git a/llvm/test/CodeGen/AVR/load.ll b/llvm/test/CodeGen/AVR/load.ll
index e2e7844b49c02..7df786c1500d6 100644
--- a/llvm/test/CodeGen/AVR/load.ll
+++ b/llvm/test/CodeGen/AVR/load.ll
@@ -100,7 +100,7 @@ for.body:                                         ; preds = 
%entry, %for.body
 
 define i8 @load8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: load8predec:
-; CHECK: ld {{.*}}, -{{[XYZ]}}
+; TODO: ld {{.*}}, -{{[XYZ]}}
 entry:
   %tobool6 = icmp eq i8 %y, 0
   br i1 %tobool6, label %while.end, label %while.body
@@ -121,8 +121,8 @@ while.end:                                        ; preds = 
%while.body, %entry
 
 define i16 @load16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: load16predec:
-; CHECK: ld {{.*}}, -{{[XYZ]}}
-; CHECK: ld {{.*}}, -{{[XYZ]}}
+; TODO: ld {{.*}}, -{{[XYZ]}}
+; TODO: ld {{.*}}, -{{[XYZ]}}
 entry:
   %tobool2 = icmp eq i16 %y, 0
   br i1 %tobool2, label %while.end, label %while.body
diff --git a/llvm/test/CodeGen/AVR/store.ll b/llvm/test/CodeGen/AVR/store.ll
index aab02709de7a6..8e7a73d24e4cd 100644
--- a/llvm/test/CodeGen/AVR/store.ll
+++ b/llvm/test/CodeGen/AVR/store.ll
@@ -94,7 +94,7 @@ while.end:                                        ; preds = 
%while.body, %entry
 
 define void @store8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: store8predec:
-; CHECK: st -{{[XYZ]}}, {{.*}}
+; TODO: st -{{[XYZ]}}, {{.*}}
 entry:
   %tobool3 = icmp eq i8 %y, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -112,8 +112,8 @@ while.end:                                        ; preds = 
%while.body, %entry
 
 define void @store16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: store16predec:
-; CHECK: st -{{[XYZ]}}, {{.*}}
-; CHECK: st -{{[XYZ]}}, {{.*}}
+; TODO: st -{{[XYZ]}}, {{.*}}
+; TODO: st -{{[XYZ]}}, {{.*}}
 entry:
   %tobool3 = icmp eq i16 %y, 0
   br i1 %tobool3, label %while.end, label %while.body

>From c32207d9d6d947d4c2ef3e1ae6c5ede2a13bbeb9 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Tue, 5 Aug 2025 10:34:22 +0200
Subject: [PATCH 5/9] keep existing postinc test

---
 llvm/test/CodeGen/AVR/load.ll | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AVR/load.ll b/llvm/test/CodeGen/AVR/load.ll
index 7df786c1500d6..e8b799e8a87eb 100644
--- a/llvm/test/CodeGen/AVR/load.ll
+++ b/llvm/test/CodeGen/AVR/load.ll
@@ -76,10 +76,32 @@ while.end:                                        ; preds = 
%while.body, %entry
   ret i8 %r.0.lcssa
 }
 
-define i16 @load16postinc(ptr %p, i16 %cnt) {
+define i16 @load16postinc(ptr %x, i16 %y) {
 ; CHECK-LABEL: load16postinc:
 ; CHECK: ld {{.*}}, {{[XYZ]}}+
 ; CHECK: ld {{.*}}, {{[XYZ]}}+
+entry:
+  %tobool2 = icmp eq i16 %y, 0
+  br i1 %tobool2, label %while.end, label %while.body
+while.body:                                       ; preds = %entry, %while.body
+  %r.05 = phi i16 [ %add, %while.body ], [ 0, %entry ]
+  %y.addr.04 = phi i16 [ %dec, %while.body ], [ %y, %entry ]
+  %x.addr.03 = phi ptr [ %incdec.ptr, %while.body ], [ %x, %entry ]
+  %dec = add nsw i16 %y.addr.04, -1
+  %incdec.ptr = getelementptr inbounds i16, ptr %x.addr.03, i16 1
+  %0 = load i16, ptr %x.addr.03
+  %add = add nsw i16 %0, %r.05
+  %tobool = icmp eq i16 %dec, 0
+  br i1 %tobool, label %while.end, label %while.body
+while.end:                                        ; preds = %while.body, %entry
+  %r.0.lcssa = phi i16 [ 0, %entry ], [ %add, %while.body ]
+  ret i16 %r.0.lcssa
+}
+
+define i16 @load16postincloopreduce(ptr %p, i16 %cnt) {
+; CHECK-LABEL: load16postincloopreduce:
+; CHECK: ld {{.*}}, {{[XYZ]}}+
+; CHECK: ld {{.*}}, {{[XYZ]}}+
 entry:
   %cmp3 = icmp sgt i16 %cnt, 0
   br i1 %cmp3, label %for.body, label %for.cond.cleanup

>From 6f220a09d584c75f7f014e8c89d88fad37dce783 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Tue, 5 Aug 2025 12:25:26 +0200
Subject: [PATCH 6/9] add test for issue

---
 llvm/test/CodeGen/AVR/issue-151080.ll | 48 +++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 llvm/test/CodeGen/AVR/issue-151080.ll

diff --git a/llvm/test/CodeGen/AVR/issue-151080.ll 
b/llvm/test/CodeGen/AVR/issue-151080.ll
new file mode 100644
index 0000000000000..3f51a16ee9db4
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/issue-151080.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=avr-none -verify-machineinstrs | FileCheck %s
+
+@ci = dso_local global [30 x i16] zeroinitializer, align 1
+declare dso_local void @foo(i16 noundef) addrspace(1)
+define void @loopreduce() {
+; CHECK-LABEL: loopreduce:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    push r14
+; CHECK-NEXT:    push r15
+; CHECK-NEXT:    push r16
+; CHECK-NEXT:    push r17
+; CHECK-NEXT:    ldi r26, lo8(ci)
+; CHECK-NEXT:    ldi r27, hi8(ci)
+; CHECK-NEXT:    ldi r16, lo8(ci+60)
+; CHECK-NEXT:    ldi r17, hi8(ci+60)
+; CHECK-NEXT:  .LBB0_1: ; %for.body
+; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    ld r24, X+
+; CHECK-NEXT:    ld r25, X+
+; CHECK-NEXT:    mov r14, r26
+; CHECK-NEXT:    mov r15, r27
+; CHECK-NEXT:    rcall foo
+; CHECK-NEXT:    mov r26, r14
+; CHECK-NEXT:    mov r27, r15
+; CHECK-NEXT:    cp r26, r16
+; CHECK-NEXT:    cpc r27, r17
+; CHECK-NEXT:    brne .LBB0_1
+; CHECK-NEXT:  ; %bb.2: ; %for.cond.cleanup
+; CHECK-NEXT:    pop r17
+; CHECK-NEXT:    pop r16
+; CHECK-NEXT:    pop r15
+; CHECK-NEXT:    pop r14
+; CHECK-NEXT:    ret
+entry:
+  br label %for.body
+for.body:                                         ; preds = %entry, %for.body
+  %i.03 = phi i16 [ 0, %entry ], [ %inc, %for.body ]
+  %arrayidx = getelementptr inbounds nuw [30 x i16], ptr @ci, i16 0, i16 %i.03
+  %0 = load i16, ptr %arrayidx, align 1
+  tail call addrspace(1) void @foo(i16 noundef %0) #3
+  %inc = add nuw nsw i16 %i.03, 1
+  %exitcond.not = icmp eq i16 %inc, 30
+  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+; Exit blocks
+for.cond.cleanup:                                 ; preds = %for.body
+  ret void
+}

>From c1f620aa68c5cd3e1426c6c6d48cb296478c2d64 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Tue, 5 Aug 2025 14:39:59 +0200
Subject: [PATCH 7/9] add test patterns

---
 llvm/test/CodeGen/AVR/issue-151080.ll | 59 ++++++++++++++++++++++++++-
 llvm/test/CodeGen/AVR/load.ll         |  6 +++
 llvm/test/CodeGen/AVR/store.ll        |  5 +++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AVR/issue-151080.ll 
b/llvm/test/CodeGen/AVR/issue-151080.ll
index 3f51a16ee9db4..f0afc47a24458 100644
--- a/llvm/test/CodeGen/AVR/issue-151080.ll
+++ b/llvm/test/CodeGen/AVR/issue-151080.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=avr-none -verify-machineinstrs | FileCheck %s
 
-@ci = dso_local global [30 x i16] zeroinitializer, align 1
 declare dso_local void @foo(i16 noundef) addrspace(1)
+@ci = dso_local global [30 x i16] zeroinitializer, align 1
 define void @loopreduce() {
 ; CHECK-LABEL: loopreduce:
 ; CHECK:       ; %bb.0: ; %entry
@@ -46,3 +46,60 @@ for.body:                                         ; preds = 
%entry, %for.body
 for.cond.cleanup:                                 ; preds = %for.body
   ret void
 }
+
+
+define void @induction() {
+; CHECK-LABEL: induction:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    push r12
+; CHECK-NEXT:    push r13
+; CHECK-NEXT:    push r14
+; CHECK-NEXT:    push r15
+; CHECK-NEXT:    push r17
+; CHECK-NEXT:    ldi r24, 8
+; CHECK-NEXT:    ldi r25, 0
+; CHECK-NEXT:    mov r14, r24
+; CHECK-NEXT:    mov r15, r25
+; CHECK-NEXT:    ldi r24, 1
+; CHECK-NEXT:    ldi r25, 0
+; CHECK-NEXT:    mov r12, r24
+; CHECK-NEXT:    mov r13, r25
+; CHECK-NEXT:    ldi r17, 3
+; CHECK-NEXT:  .LBB1_1: ; %for.body
+; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    mov r24, r12
+; CHECK-NEXT:    mov r25, r13
+; CHECK-NEXT:    rcall foo
+; CHECK-NEXT:    mov r22, r14
+; CHECK-NEXT:    mov r23, r15
+; CHECK-NEXT:    mov r24, r22
+; CHECK-NEXT:    mov r25, r23
+; CHECK-NEXT:    rcall __mulhi3
+; CHECK-NEXT:    mov r30, r14
+; CHECK-NEXT:    mov r31, r15
+; CHECK-NEXT:    adiw r30, 1
+; CHECK-NEXT:    mov r14, r30
+; CHECK-NEXT:    mov r15, r31
+; CHECK-NEXT:    cpi r24, -24
+; CHECK-NEXT:    cpc r25, r17
+; CHECK-NEXT:    brlo .LBB1_1
+; CHECK-NEXT:  ; %bb.2: ; %for.cond.cleanup
+; CHECK-NEXT:    pop r17
+; CHECK-NEXT:    pop r15
+; CHECK-NEXT:    pop r14
+; CHECK-NEXT:    pop r13
+; CHECK-NEXT:    pop r12
+; CHECK-NEXT:    ret
+entry:
+  br label %for.body
+for.body:                                         ; preds = %entry, %for.body
+  %i.03 = phi i16 [ 7, %entry ], [ %inc, %for.body ]
+  tail call addrspace(1) void @foo(i16 noundef 1) #2
+  %inc = add nuw nsw i16 %i.03, 1
+  %mul = mul nuw nsw i16 %inc, %inc
+  %cmp = icmp samesign ult i16 %mul, 1000
+  br i1 %cmp, label %for.body, label %for.cond.cleanup
+for.cond.cleanup:                                 ; preds = %for.body
+  ret void
+}
+
diff --git a/llvm/test/CodeGen/AVR/load.ll b/llvm/test/CodeGen/AVR/load.ll
index e8b799e8a87eb..070a888e69fa9 100644
--- a/llvm/test/CodeGen/AVR/load.ll
+++ b/llvm/test/CodeGen/AVR/load.ll
@@ -123,6 +123,9 @@ for.body:                                         ; preds = 
%entry, %for.body
 define i8 @load8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: load8predec:
 ; TODO: ld {{.*}}, -{{[XYZ]}}
+; TODO: ld {{.*}}, -{{[XYZ]}}
+; CHECK: sbiw {{.*}}, 1
+; CHECK: ld {{.*}}, {{[XYZ]}}
 entry:
   %tobool6 = icmp eq i8 %y, 0
   br i1 %tobool6, label %while.end, label %while.body
@@ -145,6 +148,9 @@ define i16 @load16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: load16predec:
 ; TODO: ld {{.*}}, -{{[XYZ]}}
 ; TODO: ld {{.*}}, -{{[XYZ]}}
+; CHECK: sbiw {{.*}}, 2
+; CHECK: ld {{.*}}, {{[XZ]}}
+; CHECK: ldd {{.*}}, {{[XZ]}}+1
 entry:
   %tobool2 = icmp eq i16 %y, 0
   br i1 %tobool2, label %while.end, label %while.body
diff --git a/llvm/test/CodeGen/AVR/store.ll b/llvm/test/CodeGen/AVR/store.ll
index 8e7a73d24e4cd..a1eca5d862805 100644
--- a/llvm/test/CodeGen/AVR/store.ll
+++ b/llvm/test/CodeGen/AVR/store.ll
@@ -95,6 +95,8 @@ while.end:                                        ; preds = 
%while.body, %entry
 define void @store8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: store8predec:
 ; TODO: st -{{[XYZ]}}, {{.*}}
+; CHECK: sbiw {{..*}}, 1
+; CHECK: st {{[XYZ]}}, {{.*}}
 entry:
   %tobool3 = icmp eq i8 %y, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -114,6 +116,9 @@ define void @store16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: store16predec:
 ; TODO: st -{{[XYZ]}}, {{.*}}
 ; TODO: st -{{[XYZ]}}, {{.*}}
+; CHECK: sbiw {{..*}}, 2
+; CHECK: std {{[XYZ]}}+1, {{.*}}
+; CHECK: st {{[XYZ]}}, {{.*}}
 entry:
   %tobool3 = icmp eq i16 %y, 0
   br i1 %tobool3, label %while.end, label %while.body

>From 339374a4c17bffe0ece738ffab6a8218648e88d9 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Wed, 6 Aug 2025 13:41:51 +0200
Subject: [PATCH 8/9] fix 80 column

---
 llvm/lib/Target/AVR/AVRTargetTransformInfo.h |  2 +-
 llvm/test/CodeGen/AVR/issue-151080.ll        | 38 ++++++++------------
 2 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h 
b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
index 77c2a6153f7d5..5ef2e6abc75fc 100644
--- a/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
+++ b/llvm/lib/Target/AVR/AVRTargetTransformInfo.h
@@ -1,4 +1,4 @@
-//===- AVRTargetTransformInfo.h - AVR specific TTI ---------*- C++ -*-===//
+//===- AVRTargetTransformInfo.h - AVR specific TTI --------------*- C++ 
-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/test/CodeGen/AVR/issue-151080.ll 
b/llvm/test/CodeGen/AVR/issue-151080.ll
index f0afc47a24458..9829224283f52 100644
--- a/llvm/test/CodeGen/AVR/issue-151080.ll
+++ b/llvm/test/CodeGen/AVR/issue-151080.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=avr-none -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -O=3 -mtriple=avr-none -mcpu=attiny85 -verify-machineinstrs | 
FileCheck %s
 
 declare dso_local void @foo(i16 noundef) addrspace(1)
 @ci = dso_local global [30 x i16] zeroinitializer, align 1
@@ -18,11 +18,9 @@ define void @loopreduce() {
 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    ld r24, X+
 ; CHECK-NEXT:    ld r25, X+
-; CHECK-NEXT:    mov r14, r26
-; CHECK-NEXT:    mov r15, r27
+; CHECK-NEXT:    movw r14, r26
 ; CHECK-NEXT:    rcall foo
-; CHECK-NEXT:    mov r26, r14
-; CHECK-NEXT:    mov r27, r15
+; CHECK-NEXT:    movw r26, r14
 ; CHECK-NEXT:    cp r26, r16
 ; CHECK-NEXT:    cpc r27, r17
 ; CHECK-NEXT:    brne .LBB0_1
@@ -38,7 +36,7 @@ for.body:                                         ; preds = 
%entry, %for.body
   %i.03 = phi i16 [ 0, %entry ], [ %inc, %for.body ]
   %arrayidx = getelementptr inbounds nuw [30 x i16], ptr @ci, i16 0, i16 %i.03
   %0 = load i16, ptr %arrayidx, align 1
-  tail call addrspace(1) void @foo(i16 noundef %0) #3
+  tail call addrspace(1) void @foo(i16 noundef %0)
   %inc = add nuw nsw i16 %i.03, 1
   %exitcond.not = icmp eq i16 %inc, 30
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
@@ -47,9 +45,8 @@ for.cond.cleanup:                                 ; preds = 
%for.body
   ret void
 }
 
-
-define void @induction() {
-; CHECK-LABEL: induction:
+define void @indvar() {
+; CHECK-LABEL: indvar:
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    push r12
 ; CHECK-NEXT:    push r13
@@ -58,28 +55,21 @@ define void @induction() {
 ; CHECK-NEXT:    push r17
 ; CHECK-NEXT:    ldi r24, 8
 ; CHECK-NEXT:    ldi r25, 0
-; CHECK-NEXT:    mov r14, r24
-; CHECK-NEXT:    mov r15, r25
+; CHECK-NEXT:    movw r14, r24
 ; CHECK-NEXT:    ldi r24, 1
 ; CHECK-NEXT:    ldi r25, 0
-; CHECK-NEXT:    mov r12, r24
-; CHECK-NEXT:    mov r13, r25
+; CHECK-NEXT:    movw r12, r24
 ; CHECK-NEXT:    ldi r17, 3
 ; CHECK-NEXT:  .LBB1_1: ; %for.body
 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    mov r24, r12
-; CHECK-NEXT:    mov r25, r13
+; CHECK-NEXT:    movw r24, r12
 ; CHECK-NEXT:    rcall foo
-; CHECK-NEXT:    mov r22, r14
-; CHECK-NEXT:    mov r23, r15
-; CHECK-NEXT:    mov r24, r22
-; CHECK-NEXT:    mov r25, r23
+; CHECK-NEXT:    movw r22, r14
+; CHECK-NEXT:    movw r24, r22
 ; CHECK-NEXT:    rcall __mulhi3
-; CHECK-NEXT:    mov r30, r14
-; CHECK-NEXT:    mov r31, r15
+; CHECK-NEXT:    movw r30, r14
 ; CHECK-NEXT:    adiw r30, 1
-; CHECK-NEXT:    mov r14, r30
-; CHECK-NEXT:    mov r15, r31
+; CHECK-NEXT:    movw r14, r30
 ; CHECK-NEXT:    cpi r24, -24
 ; CHECK-NEXT:    cpc r25, r17
 ; CHECK-NEXT:    brlo .LBB1_1
@@ -94,7 +84,7 @@ entry:
   br label %for.body
 for.body:                                         ; preds = %entry, %for.body
   %i.03 = phi i16 [ 7, %entry ], [ %inc, %for.body ]
-  tail call addrspace(1) void @foo(i16 noundef 1) #2
+  tail call addrspace(1) void @foo(i16 noundef 1)
   %inc = add nuw nsw i16 %i.03, 1
   %mul = mul nuw nsw i16 %inc, %inc
   %cmp = icmp samesign ult i16 %mul, 1000

>From d5809f9aef1a77cd731d48aff72368b3b5f5c836 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbr...@gmail.com>
Date: Wed, 6 Aug 2025 14:58:08 +0200
Subject: [PATCH 9/9] more specific tests

---
 llvm/test/CodeGen/AVR/load.ll  | 12 ++++++------
 llvm/test/CodeGen/AVR/store.ll | 11 ++++++-----
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/llvm/test/CodeGen/AVR/load.ll b/llvm/test/CodeGen/AVR/load.ll
index 070a888e69fa9..6a1e067a21aed 100644
--- a/llvm/test/CodeGen/AVR/load.ll
+++ b/llvm/test/CodeGen/AVR/load.ll
@@ -123,9 +123,8 @@ for.body:                                         ; preds = 
%entry, %for.body
 define i8 @load8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: load8predec:
 ; TODO: ld {{.*}}, -{{[XYZ]}}
-; TODO: ld {{.*}}, -{{[XYZ]}}
-; CHECK: sbiw {{.*}}, 1
-; CHECK: ld {{.*}}, {{[XYZ]}}
+; CHECK: sbiw r26, 1
+; CHECK: ld {{.*}}, X
 entry:
   %tobool6 = icmp eq i8 %y, 0
   br i1 %tobool6, label %while.end, label %while.body
@@ -148,9 +147,10 @@ define i16 @load16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: load16predec:
 ; TODO: ld {{.*}}, -{{[XYZ]}}
 ; TODO: ld {{.*}}, -{{[XYZ]}}
-; CHECK: sbiw {{.*}}, 2
-; CHECK: ld {{.*}}, {{[XZ]}}
-; CHECK: ldd {{.*}}, {{[XZ]}}+1
+; CHECK: sbiw r24, 2
+; CHECK: movw r30, r24
+; CHECK: ld {{.*}}, Z
+; CHECK: ldd {{.*}}, Z+1
 entry:
   %tobool2 = icmp eq i16 %y, 0
   br i1 %tobool2, label %while.end, label %while.body
diff --git a/llvm/test/CodeGen/AVR/store.ll b/llvm/test/CodeGen/AVR/store.ll
index a1eca5d862805..9c4164557721c 100644
--- a/llvm/test/CodeGen/AVR/store.ll
+++ b/llvm/test/CodeGen/AVR/store.ll
@@ -95,8 +95,8 @@ while.end:                                        ; preds = 
%while.body, %entry
 define void @store8predec(ptr %x, i8 %y) {
 ; CHECK-LABEL: store8predec:
 ; TODO: st -{{[XYZ]}}, {{.*}}
-; CHECK: sbiw {{..*}}, 1
-; CHECK: st {{[XYZ]}}, {{.*}}
+; CHECK: sbiw r26, 1
+; CHECK: st X, {{.*}}
 entry:
   %tobool3 = icmp eq i8 %y, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -116,9 +116,10 @@ define void @store16predec(ptr %x, i16 %y) {
 ; CHECK-LABEL: store16predec:
 ; TODO: st -{{[XYZ]}}, {{.*}}
 ; TODO: st -{{[XYZ]}}, {{.*}}
-; CHECK: sbiw {{..*}}, 2
-; CHECK: std {{[XYZ]}}+1, {{.*}}
-; CHECK: st {{[XYZ]}}, {{.*}}
+; CHECK: sbiw r24, 2
+; CHECK: movw r30, r24
+; CHECK: std Z+1, {{.*}}
+; CHECK: st Z, {{.*}}
 entry:
   %tobool3 = icmp eq i16 %y, 0
   br i1 %tobool3, label %while.end, label %while.body

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to