https://github.com/OCHyams created https://github.com/llvm/llvm-project/pull/133482
SimplifyCFG folds `b` into `a`. +-----------+ | v --> a --> b --> c --> d --> | ^ +-----------------+ Remap source atoms in `b` so that the duplicated instructions are analysed independently to determine is_stmt positions. This is necessary as the contents of `b` may be folded into multiple preds in this way. Add multi-pred test. >From eeb24e30bb00840cd2b1f53da975a3640e9446d0 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams <orlando.hy...@sony.com> Date: Mon, 24 Mar 2025 13:48:07 +0000 Subject: [PATCH] [KeyInstr][SimplifyCFG] Remap atoms when folding br to common succ into pred SimplifyCFG folds `b` into `a`. +-----------+ | v --> a --> b --> c --> d --> | ^ +-----------------+ Remap source atoms in `b` so that the duplicated instructions are analysed independently to determine is_stmt positions. This is necessary as the contents of `b` may be folded into multiple preds in this way. Add multi-pred test. --- llvm/include/llvm/IR/DebugLoc.h | 10 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 32 ++++++-- .../Generic/simplifycfg-branch-fold.ll | 81 +++++++++++++++++++ 3 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll diff --git a/llvm/include/llvm/IR/DebugLoc.h b/llvm/include/llvm/IR/DebugLoc.h index c22d3e9b10d27..7fdedc4acd919 100644 --- a/llvm/include/llvm/IR/DebugLoc.h +++ b/llvm/include/llvm/IR/DebugLoc.h @@ -76,6 +76,16 @@ namespace llvm { LLVMContext &Ctx, DenseMap<const MDNode *, MDNode *> &Cache); + /// Return true if the source locations match, ignoring isImplicitCode and + /// source atom info. + bool isSameSourceLocation(const DebugLoc &Other) const { + if (get() == Other.get()) + return true; + return ((bool)*this == (bool)Other) && getLine() == Other.getLine() && + getCol() == Other.getCol() && getScope() == Other.getScope() && + getInlinedAt() == Other.getInlinedAt(); + } + unsigned getLine() const; unsigned getCol() const; MDNode *getScope() const; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index fd83ec1a7f4fe..1ba1e4ac81000 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -73,6 +73,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LockstepReverseIterator.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -1129,13 +1130,17 @@ static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( Instruction *NewBonusInst = BonusInst.clone(); - if (!isa<DbgInfoIntrinsic>(BonusInst) && - PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) { - // Unless the instruction has the same !dbg location as the original - // branch, drop it. When we fold the bonus instructions we want to make - // sure we reset their debug locations in order to avoid stepping on - // dead code caused by folding dead branches. - NewBonusInst->setDebugLoc(DebugLoc()); + if (!isa<DbgInfoIntrinsic>(BonusInst)) { + if (!NewBonusInst->getDebugLoc().isSameSourceLocation( + PTI->getDebugLoc())) { + // Unless the instruction has the same !dbg location as the original + // branch, drop it. When we fold the bonus instructions we want to make + // sure we reset their debug locations in order to avoid stepping on + // dead code caused by folding dead branches. + NewBonusInst->setDebugLoc(DebugLoc()); + } else if (const DebugLoc &DL = NewBonusInst->getDebugLoc()) { + mapAtomInstance(DL, VMap); + } } RemapInstruction(NewBonusInst, VMap, @@ -1182,6 +1187,19 @@ static void cloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( U.set(NewBonusInst); } } + + // Key Instructions: We may have propagated atom info into the pred. If the + // pred's terminator already has atom info do nothing as merging would drop + // one atom group anyway. If it doesn't, propagte the remapped atom group + // from BB's terminator. + if (auto &PredDL = PredBlock->getTerminator()->getDebugLoc()) { + auto &DL = BB->getTerminator()->getDebugLoc(); + if (!PredDL->getAtomGroup() && DL && DL->getAtomGroup() && + PredDL.isSameSourceLocation(DL)) { + PredBlock->getTerminator()->setDebugLoc(DL); + RemapSourceAtom(PredBlock->getTerminator(), VMap); + } + } } bool SimplifyCFGOpt::performValueComparisonIntoPredecessorFolding( diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll new file mode 100644 index 0000000000000..8746f242007c3 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll @@ -0,0 +1,81 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt %s -S -passes=simplifycfg -bonus-inst-threshold=2 | FileCheck %s + +;; Block d gets folded into preds b and c. Check the cloned instructions get +;; remapped DILocation atomGroup numbers in each of the preds. Additionally +;; check that the branches each inherit the atomGroup of the folded branch. + +declare i32 @g(...) +define void @f(i1 %c0, i1 %c1, i1 %c2, i32 %x, i32 %y) !dbg !17 { +; CHECK-LABEL: define void @f( +; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) !dbg [[DBG6:![0-9]+]] { +; CHECK-NEXT: [[A:.*:]] +; CHECK-NEXT: br i1 [[C0]], label %[[B:.*]], label %[[C:.*]] +; CHECK: [[B]]: +; CHECK-NEXT: [[AND_OLD:%.*]] = and i32 [[X]], [[Y]], !dbg [[DBG8:![0-9]+]] +; CHECK-NEXT: [[CMP_OLD:%.*]] = icmp eq i32 [[AND_OLD]], 0, !dbg [[DBG9:![0-9]+]] +; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[C1]], i1 true, i1 [[CMP_OLD]], !dbg [[DBG10:![0-9]+]] +; CHECK-NEXT: br i1 [[OR_COND1]], label %[[F:.*]], label %[[E:.*]], !dbg [[DBG11:![0-9]+]] +; CHECK: [[C]]: +; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]], !dbg [[DBG12:![0-9]+]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0, !dbg [[DBG13:![0-9]+]] +; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 true, i1 [[CMP]], !dbg [[DBG10]] +; CHECK-NEXT: br i1 [[OR_COND]], label %[[F]], label %[[E]], !dbg [[DBG14:![0-9]+]] +; CHECK: [[E]]: +; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 (...) @g() +; CHECK-NEXT: br label %[[F]] +; CHECK: [[F]]: +; CHECK-NEXT: ret void +; +a: + br i1 %c0, label %b, label %c + +b: + br i1 %c1, label %f, label %d, !dbg !18 + +c: + br i1 %c2, label %f, label %d, !dbg !18 + +d: + %and = and i32 %x, %y, !dbg !19 + %cmp = icmp eq i32 %and, 0, !dbg !20 + br i1 %cmp, label %f, label %e, !dbg !21 + +e: + %7 = tail call i32 (...) @g() + br label %f + +f: + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.debugify = !{!3, !4} +!llvm.module.flags = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "a.ll", directory: "/") +!2 = !{} +!3 = !{i32 9} +!4 = !{i32 0} +!5 = !{i32 2, !"Debug Info Version", i32 3} +!7 = !DISubroutineType(types: !2) +!17 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!18 = !DILocation(line: 10, column: 10, scope: !17) +!19 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 1, atomRank: 2) +!20 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 2, atomRank: 2) +!21 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 2, atomRank: 1) +;. +; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META2:![0-9]+]]) +; CHECK: [[META1]] = !DIFile(filename: "a.ll", directory: {{.*}}) +; CHECK: [[META2]] = !{} +; CHECK: [[DBG6]] = distinct !DISubprogram(name: "f", scope: null, file: [[META1]], line: 1, type: [[META7:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META2]]) +; CHECK: [[META7]] = !DISubroutineType(types: [[META2]]) +; CHECK: [[DBG8]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 5, atomRank: 2) +; CHECK: [[DBG9]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 6, atomRank: 2) +; CHECK: [[DBG10]] = !DILocation(line: 10, column: 10, scope: [[DBG6]]) +; CHECK: [[DBG11]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 6, atomRank: 1) +; CHECK: [[DBG12]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 3, atomRank: 2) +; CHECK: [[DBG13]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 4, atomRank: 2) +; CHECK: [[DBG14]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], atomGroup: 4, atomRank: 1) +;. _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits