[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