[llvm] 83729e6 - [SelectionDAG] Disable FastISel for swiftasync functions (#70741)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 08:27:33 PST 2023


Author: Felipe de Azevedo Piovezan
Date: 2023-11-13T08:27:29-08:00
New Revision: 83729e6716591421e4452bc31741a485861fb229

URL: https://github.com/llvm/llvm-project/commit/83729e6716591421e4452bc31741a485861fb229
DIFF: https://github.com/llvm/llvm-project/commit/83729e6716591421e4452bc31741a485861fb229.diff

LOG: [SelectionDAG] Disable FastISel for swiftasync functions (#70741)

Most (x86) swiftasync functions tend to use both SelectionDAGISel and
FastISel lowering:
* FastISel argument lowering can only handle C calling convention.
* FastISel fails mid-BB in a number of ways, including in simple `ret
void` instructions under certain circumstances.

This dance of SelectionDAG (argument) -> FastISel (some instructions) ->
SelectionDAG(remaining instructions) is lossy; in particular, Argument
information lowering is cleared after that first SelectionDAG run.

Since swiftasync functions rely heavily on proper Argument lowering for
debug information, this patch disables the use of FastISel in such
functions.

Added: 
    llvm/test/CodeGen/X86/swift-async-no-fastisel.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 0cc426254806ddf..0a8afa782f1ca47 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -204,6 +204,16 @@ static RegisterScheduler
 defaultListDAGScheduler("default", "Best scheduler for the target",
                         createDefaultScheduler);
 
+static bool dontUseFastISelFor(const Function &Fn) {
+  // Don't enable FastISel for functions with swiftasync Arguments.
+  // Debug info on those is reliant on good Argument lowering, and FastISel is
+  // not capable of lowering the entire function. Mixing the two selectors tend
+  // to result in poor lowering of Arguments.
+  return any_of(Fn.args(), [](const Argument &Arg) {
+    return Arg.hasAttribute(Attribute::AttrKind::SwiftAsync);
+  });
+}
+
 namespace llvm {
 
   //===--------------------------------------------------------------------===//
@@ -219,21 +229,23 @@ namespace llvm {
         : IS(ISel) {
       SavedOptLevel = IS.OptLevel;
       SavedFastISel = IS.TM.Options.EnableFastISel;
-      if (NewOptLevel == SavedOptLevel)
-        return;
-      IS.OptLevel = NewOptLevel;
-      IS.TM.setOptLevel(NewOptLevel);
-      LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
-                        << IS.MF->getFunction().getName() << "\n");
-      LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel) << " ; After: -O"
-                        << static_cast<int>(NewOptLevel) << "\n");
-      if (NewOptLevel == CodeGenOptLevel::None) {
-        IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
-        LLVM_DEBUG(
-            dbgs() << "\tFastISel is "
-                   << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
-                   << "\n");
+      if (NewOptLevel != SavedOptLevel) {
+        IS.OptLevel = NewOptLevel;
+        IS.TM.setOptLevel(NewOptLevel);
+        LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
+                          << IS.MF->getFunction().getName() << "\n");
+        LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
+                          << " ; After: -O" << static_cast<int>(NewOptLevel)
+                          << "\n");
+        if (NewOptLevel == CodeGenOptLevel::None)
+          IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
       }
+      if (dontUseFastISelFor(IS.MF->getFunction()))
+        IS.TM.setFastISel(false);
+      LLVM_DEBUG(
+          dbgs() << "\tFastISel is "
+                 << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
+                 << "\n");
     }
 
     ~OptLevelChanger() {

diff  --git a/llvm/test/CodeGen/X86/swift-async-no-fastisel.ll b/llvm/test/CodeGen/X86/swift-async-no-fastisel.ll
new file mode 100644
index 000000000000000..b60c8183480b695
--- /dev/null
+++ b/llvm/test/CodeGen/X86/swift-async-no-fastisel.ll
@@ -0,0 +1,40 @@
+; RUN: llc %s --fast-isel=true --stop-after=finalize-isel -o %t \
+; RUN:   -experimental-debug-variable-locations=false --global-isel=false
+; RUN:   FileCheck %s < %t
+; RUN:   FileCheck %s --check-prefix=INTRINSICS < %t
+
+
+source_filename = "ir_x86.ll"
+target triple = "x86_64-*"
+
+define swifttailcc void @foo(ptr swiftasync %0) !dbg !43 {
+  call void asm sideeffect "", "r"(ptr %0), !dbg !62
+  ; FastISEL doesn't preserve %0 here. Check that this function is lowered with SelectionDAG.
+  call void @llvm.dbg.value(metadata ptr %0, metadata !54, metadata !DIExpression(DW_OP_plus_uconst, 4242)), !dbg !62
+  ret void, !dbg !62
+}
+
+; CHECK-NOT: DBG_VALUE $noreg
+; INTRINSICS: ![[VAR:[0-9]*]] = !DILocalVariable(name: "msg",
+; INTRINSICS: DBG_VALUE {{.*}}, ![[VAR]], !DIExpression(DW_OP_plus_uconst, 4242)
+
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.module.flags = !{!6, !7, !8, !9, !10}
+!llvm.dbg.cu = !{!16}
+
+!6 = !{i32 7, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !{i32 1, !"wchar_size", i32 4}
+!9 = !{i32 8, !"PIC Level", i32 2}
+!10 = !{i32 7, !"uwtable", i32 2}
+!16 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !17, producer: "blah", emissionKind: FullDebug)
+!17 = !DIFile(filename: "blah", directory: "blah")
+!43 = distinct !DISubprogram(name: "blah", linkageName: "blah", file: !17, line: 87, type: !44, scopeLine: 87, unit: !16, retainedNodes: !48)
+!44 = !DISubroutineType(types: !45)
+!45 = !{!46}
+!46 = !DICompositeType(tag: DW_TAG_structure_type, name: "blah")
+!48 = !{!54}
+!54 = !DILocalVariable(name: "msg", arg: 1, scope: !43, file: !17, line: 87, type: !46)
+!62 = !DILocation(line: 87, column: 30, scope: !43)


        


More information about the llvm-commits mailing list