diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -561,15 +561,11 @@ MachineBasicBlock::iterator MBBI = MBB.end(); DebugLoc DL; if (!MBB.empty()) { + MBBI = MBB.getLastNonDebugInstr(); + if (MBBI != MBB.end()) + DL = MBBI->getDebugLoc(); + MBBI = MBB.getFirstTerminator(); - if (MBBI == MBB.end()) - MBBI = MBB.getLastNonDebugInstr(); - DL = MBBI->getDebugLoc(); - - // If this is not a terminator, the actual insert location should be after the - // last instruction. - if (!MBBI->isTerminator()) - MBBI = std::next(MBBI); // If callee-saved registers are saved via libcall, place stack adjustment // before this call. diff --git a/llvm/test/CodeGen/RISCV/xform_ah-min.ll b/llvm/test/CodeGen/RISCV/xform_ah-min.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/xform_ah-min.ll @@ -0,0 +1,86 @@ +; RUN: llc -mtriple=riscv64 -enable-shrink-wrap < %s +; Check that we don't crash + +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +target triple = "riscv64" + +%struct.a = type { i32, i16 } + +; Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +define dso_local signext i32 @c(%struct.a* noundef readonly %d) local_unnamed_addr #0 !dbg !8 { +entry: + call void @llvm.dbg.value(metadata %struct.a* %d, metadata !20, metadata !DIExpression()), !dbg !22 + %cmp = icmp eq %struct.a* %d, null, !dbg !23 + br i1 %cmp, label %cleanup, label %if.end, !dbg !25 + +if.end: ; preds = %entry + %b = getelementptr inbounds %struct.a, %struct.a* %d, i64 0, i32 0, !dbg !26 + %0 = load i32, i32* %b, align 4, !dbg !26, !tbaa !27 + %switch = icmp ult i32 %0, 2, !dbg !33 + br i1 %switch, label %sw.epilog.sink.split, label %sw.epilog, !dbg !33 + +sw.epilog.sink.split: ; preds = %if.end + %ab2 = getelementptr inbounds %struct.a, %struct.a* %d, i64 0, i32 1, !dbg !34 + %1 = load i16, i16* %ab2, align 4, !dbg !34, !tbaa !36 + br label %sw.epilog, !dbg !34 + +sw.epilog: ; preds = %if.end, %sw.epilog.sink.split + %a.0.shrunk = phi i16 [ 0, %if.end ], [ %1, %sw.epilog.sink.split ] + %a.0 = zext i16 %a.0.shrunk to i32, !dbg !34 + call void @llvm.dbg.value(metadata i32 %a.0, metadata !21, metadata !DIExpression()), !dbg !22 + br label %cleanup, !dbg !37 + +cleanup: ; preds = %entry, %sw.epilog + %retval.0 = phi i32 [ %a.0, %sw.epilog ], [ 0, %entry ], !dbg !22 + ret i32 %retval.0, !dbg !38 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+a,+c,+m,+relax,-save-restore" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "xform_ah-min.c", directory: "") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 1, !"target-abi", !"lp64"} +!6 = !{i32 1, !"SmallDataLimit", i32 8} +!7 = !{!"clang version 15.0.0"} +!8 = distinct !DISubprogram(name: "c", scope: !1, file: !1, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !19) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !12} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!13 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "a", file: !1, line: 1, size: 64, elements: !15) +!15 = !{!16, !17} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 2, baseType: !11, size: 32) +!17 = !DIDerivedType(tag: DW_TAG_member, name: "ab", scope: !14, file: !1, line: 3, baseType: !18, size: 16, offset: 32) +!18 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned) +!19 = !{!20, !21} +!20 = !DILocalVariable(name: "d", arg: 1, scope: !8, file: !1, line: 6, type: !12) +!21 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 7, type: !11) +!22 = !DILocation(line: 0, scope: !8) +!23 = !DILocation(line: 8, column: 9, scope: !24) +!24 = distinct !DILexicalBlock(scope: !8, file: !1, line: 8, column: 7) +!25 = !DILocation(line: 8, column: 7, scope: !8) +!26 = !DILocation(line: 10, column: 14, scope: !8) +!27 = !{!28, !29, i64 0} +!28 = !{!"a", !29, i64 0, !32, i64 4} +!29 = !{!"int", !30, i64 0} +!30 = !{!"omnipotent char", !31, i64 0} +!31 = !{!"Simple C/C++ TBAA"} +!32 = !{!"short", !30, i64 0} +!33 = !DILocation(line: 10, column: 3, scope: !8) +!34 = !DILocation(line: 0, scope: !35) +!35 = distinct !DILexicalBlock(scope: !8, file: !1, line: 10, column: 17) +!36 = !{!28, !32, i64 4} +!37 = !DILocation(line: 20, column: 3, scope: !8) +!38 = !DILocation(line: 21, column: 1, scope: !8)