[llvm] d58f112 - Prevent FENTRY_CALL reordering

Ilya Leoshkevich via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 8 16:01:48 PST 2020


Author: Ilya Leoshkevich
Date: 2020-12-09T00:59:01+01:00
New Revision: d58f112ce03877f73200591cd3c9b38e41e46afe

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

LOG: Prevent FENTRY_CALL reordering

FEntryInserter prepends FENTRY_CALL to the first basic block. In case
there are other instructions, PostRA Machine Instruction Scheduler can
move FENTRY_CALL call around. This actually occurs on SystemZ (see the
testcase). This is bad for the following reasons:

* FENTRY_CALL clobbers registers.
* Linux Kernel depends on whatever FENTRY_CALL expands to to be the very
  first instruction in the function.

Fix by adding isCall attribute to FENTRY_CALL, which prevents reordering
by making it a scheduling boundary for PostRA Machine Instruction
Scheduler.

Reviewed By: niravd

Differential Revision: https://reviews.llvm.org/D91218

Added: 
    llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
    llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll

Modified: 
    llvm/include/llvm/Target/Target.td
    llvm/lib/CodeGen/MachineInstr.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 9664f70c7a02..1c97d70a477f 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1282,6 +1282,7 @@ def FENTRY_CALL : StandardPseudoInstruction {
   let InOperandList = (ins);
   let AsmString = "# FEntry call";
   let usesCustomInserter = true;
+  let isCall = true;
   let mayLoad = true;
   let mayStore = true;
   let hasSideEffects = true;

diff  --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index fd658cdb41b9..900abd2b260d 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -713,6 +713,7 @@ bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {
   case TargetOpcode::PATCHPOINT:
   case TargetOpcode::STACKMAP:
   case TargetOpcode::STATEPOINT:
+  case TargetOpcode::FENTRY_CALL:
     return false;
   }
   return true;

diff  --git a/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll b/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
new file mode 100644
index 000000000000..e78c5aad0240
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/fentry-debug-info.ll
@@ -0,0 +1,22 @@
+; Test that compiling with fentry and debuginfo works.
+;
+; RUN: llc %s -mtriple=s390x-linux-gnu -o - -verify-machineinstrs
+
+define dso_local void @_Z1av() local_unnamed_addr #0 !dbg !7 {
+entry:
+  ret void
+}
+
+attributes #0 = { norecurse nounwind readnone "fentry-call"="true" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "a.cpp", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DISubprogram(name: "a", linkageName: "_Z1av", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}

diff  --git a/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll b/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll
new file mode 100644
index 000000000000..f8a9409ed84e
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/fentry-no-reorder.ll
@@ -0,0 +1,19 @@
+; RUN: llc %s -mtriple=s390x-linux-gnu -mcpu=zEC12 -o - -verify-machineinstrs \
+; RUN:   | FileCheck %s
+
+ at PawnTT = dso_local local_unnamed_addr global [2048 x i8] zeroinitializer, align 2
+
+define dso_local void @clear_pawn_tt() local_unnamed_addr #0 {
+entry:
+  call void @llvm.memset.p0i8.i64(i8* nonnull align 2 dereferenceable(2048) getelementptr inbounds ([2048 x i8], [2048 x i8]* @PawnTT, i64 0, i64 0), i8 0, i64 2048, i1 false)
+  ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
+
+attributes #0 = { nofree nounwind writeonly "fentry-call"="true" }
+attributes #1 = { argmemonly nofree nosync nounwind willreturn writeonly }
+
+; CHECK: clear_pawn_tt: # @clear_pawn_tt
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: brasl %r0, __fentry__ at PLT


        


More information about the llvm-commits mailing list