diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 9747ad0c5cd58..bfd7f1c6b07eb 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -1114,8 +1114,22 @@ bool AVRTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, if (AVR::isProgramMemoryAccess(LD)) return false; + SDValue Ptr; + if (LoadSDNode *LD = dyn_cast(N)) { + Ptr = LD->getBasePtr(); + } else if (StoreSDNode *ST = dyn_cast(N)) { + Ptr = ST->getBasePtr(); + } else + return false; + Base = Op->getOperand(0); Offset = DAG.getConstant(RHSC, DL, MVT::i8); + + // Post-indexing updates the base, so it's not a valid transform + // if that's not the same as the load's pointer. + if (Ptr != Base) + return false; + AM = ISD::POST_INC; return true; diff --git a/llvm/test/CodeGen/AVR/issue-145040.ll b/llvm/test/CodeGen/AVR/issue-145040.ll new file mode 100644 index 0000000000000..481c5fa852a1d --- /dev/null +++ b/llvm/test/CodeGen/AVR/issue-145040.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -O=2 -mtriple=avr-none --mcpu=avr128db28 -verify-machineinstrs | FileCheck %s + +declare dso_local void @nil(i16 noundef) local_unnamed_addr addrspace(1) #1 +!3 = !{!4, !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} + +define void @complex_sbi() { +; CHECK: sbi 1, 7 +entry: + br label %while.cond +while.cond: ; preds = %while.cond, %entry + %s.0 = phi i16 [ 0, %entry ], [ %inc, %while.cond ] + %inc = add nuw nsw i16 %s.0, 1 + %0 = load volatile i8, ptr inttoptr (i16 1 to ptr), align 1, !tbaa !3 + %or = or i8 %0, -128 + store volatile i8 %or, ptr inttoptr (i16 1 to ptr), align 1, !tbaa !3 + %and = and i16 %inc, 15 + %add = add nuw nsw i16 %and, 1 + tail call addrspace(1) void @nil(i16 noundef %add) #2 + br label %while.cond +} +