Unverified Commit 83729e67 authored by Felipe de Azevedo Piovezan's avatar Felipe de Azevedo Piovezan Committed by GitHub
Browse files

[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.
parent 9aefa5cb
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -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,22 +229,24 @@ namespace llvm {
        : IS(ISel) {
      SavedOptLevel = IS.OptLevel;
      SavedFastISel = IS.TM.Options.EnableFastISel;
      if (NewOptLevel == SavedOptLevel)
        return;
      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) {
        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() {
      if (IS.OptLevel == SavedOptLevel)
+40 −0
Original line number Diff line number Diff line
; 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)