diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h @@ -39,6 +39,7 @@ void Select(SDNode *Node) override; bool SelectBaseAddr(SDValue Addr, SDValue &Base); + bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base); bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); bool selectShiftMaskGRLen(SDValue N, SDValue &ShAmt) { diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp @@ -88,6 +88,14 @@ return true; } +bool LoongArchDAGToDAGISel::selectNonFIBaseAddr(SDValue Addr, SDValue &Base) { + // If this is FrameIndex, don't select it. + if (isa(Addr)) + return false; + Base = Addr; + return true; +} + bool LoongArchDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt) { // Shift instructions on LoongArch only read the lower 5 or 6 bits of the diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -248,6 +248,7 @@ }]>; def BaseAddr : ComplexPattern; +def NonFIBaseAddr : ComplexPattern; def fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa), (fma node:$fj, node:$fk, node:$fa), [{ @@ -987,8 +988,8 @@ // LA64 register-register-addressed loads let Predicates = [IsLA64] in { class RegRegLdPat - : Pat<(vt (LoadOp (add BaseAddr:$rj, GPR:$rk))), - (Inst BaseAddr:$rj, GPR:$rk)>; + : Pat<(vt (LoadOp (add NonFIBaseAddr:$rj, GPR:$rk))), + (Inst NonFIBaseAddr:$rj, GPR:$rk)>; def : RegRegLdPat; def : RegRegLdPat; @@ -1036,8 +1037,8 @@ let Predicates = [IsLA64] in { class RegRegStPat - : Pat<(StoreOp (vt StTy:$rd), (add BaseAddr:$rj, GPR:$rk)), - (Inst StTy:$rd, BaseAddr:$rj, GPR:$rk)>; + : Pat<(StoreOp (vt StTy:$rd), (add NonFIBaseAddr:$rj, GPR:$rk)), + (Inst StTy:$rd, NonFIBaseAddr:$rj, GPR:$rk)>; def : RegRegStPat; def : RegRegStPat; diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp --- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp @@ -114,6 +114,9 @@ assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); MachineInstr &MI = *II; + assert(MI.getOperand(FIOperandNum + 1).isImm() && + "Unexpected FI-consuming insn"); + MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MI.getParent()->getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); diff --git a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll @@ -0,0 +1,18 @@ +; RUN: llc --mtriple=loongarch32 < %s +; RUN: llc --mtriple=loongarch64 < %s + +@.str.2 = external dso_local unnamed_addr constant [69 x i8], align 1 + +define dso_local void @main() { +entry: + %n0 = alloca [2 x [3 x i32]], align 4 + %0 = load i32, ptr poison, align 4 + %idxprom15 = sext i32 %0 to i64 + %arrayidx16 = getelementptr inbounds [2 x [3 x i32]], ptr %n0, i64 0, i64 %idxprom15 + %arrayidx17 = getelementptr inbounds [3 x i32], ptr %arrayidx16, i64 0, i64 0 + %1 = load i32, ptr %arrayidx17, align 4 + call void (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %1) + ret void +} + +declare void @printf(ptr, ...) diff --git a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll @@ -0,0 +1,21 @@ +; RUN: llc --mtriple=loongarch32 < %s +; RUN: llc --mtriple=loongarch64 < %s + +define void @_ZN12_GLOBAL__N_111DumpVisitorclIN4llvm16itanium_demangle8FoldExprEEEvPKT_() { +entry: + %ref.tmp6.i.i = alloca [4 x i8], align 1 + br label %for.cond.i.i + +for.cond.i.i: ; preds = %for.body.i.i, %entry + %__begin0.0.add.i.i = add nuw nsw i64 poison, 1 + br label %for.body.i.i + +for.body.i.i: ; preds = %for.cond.i.i + %__begin0.0.ptr.i.i = getelementptr inbounds i8, ptr %ref.tmp6.i.i, i64 %__begin0.0.add.i.i + %0 = load i8, ptr %__begin0.0.ptr.i.i, align 1 + %tobool18.not.i.i = icmp eq i8 %0, 0 + br i1 %tobool18.not.i.i, label %for.cond.i.i, label %exit + +exit: ; preds = %for.body.i.i + unreachable +}