[llvm] c0214db - [llvm] Mark CFGuard fn ptr symbol as DSO local and add tests for mingw
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 23 13:40:28 PDT 2022
Author: Alvin Wong
Date: 2022-08-23T23:39:39+03:00
New Revision: c0214db51ad623361a59844e657748aed32f8d87
URL: https://github.com/llvm/llvm-project/commit/c0214db51ad623361a59844e657748aed32f8d87
DIFF: https://github.com/llvm/llvm-project/commit/c0214db51ad623361a59844e657748aed32f8d87.diff
LOG: [llvm] Mark CFGuard fn ptr symbol as DSO local and add tests for mingw
For mingw target, if a symbol is not marked DSO local, a `.refptr` is
generated for it. This makes CFG check calls use an extra pointer
dereference, which adds extra overhead compared to the MSVC version,
so mark the CFG guard check funciton pointer DSO local to stop it.
This should have no effect on MSVC target.
Also adapt the existing cfguard tests to run for mingw targets, so that
this change is checked.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D132331
Added:
llvm/test/CodeGen/WinCFGuard/cfguard-mingw.ll
llvm/test/CodeGen/X86/cfguard-checks-funclet.ll
Modified:
llvm/lib/Transforms/CFGuard/CFGuard.cpp
llvm/test/CodeGen/AArch64/cfguard-checks.ll
llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
llvm/test/CodeGen/ARM/cfguard-checks.ll
llvm/test/CodeGen/ARM/cfguard-module-flag.ll
llvm/test/CodeGen/WinCFGuard/cfguard-cast.ll
llvm/test/CodeGen/WinCFGuard/cfguard-giats.ll
llvm/test/CodeGen/X86/cfguard-checks.ll
llvm/test/CodeGen/X86/cfguard-module-flag.ll
llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
llvm/test/CodeGen/X86/cfguard-x86-vectorcall.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/CFGuard/CFGuard.cpp b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
index 5fc5295969d0..280348a50ff0 100644
--- a/llvm/lib/Transforms/CFGuard/CFGuard.cpp
+++ b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
@@ -241,14 +241,21 @@ bool CFGuard::doInitialization(Module &M) {
GuardFnPtrType = PointerType::get(GuardFnType, 0);
// Get or insert the guard check or dispatch global symbols.
+ llvm::StringRef GuardFnName;
if (GuardMechanism == CF_Check) {
- GuardFnGlobal =
- M.getOrInsertGlobal("__guard_check_icall_fptr", GuardFnPtrType);
+ GuardFnName = "__guard_check_icall_fptr";
+ } else if (GuardMechanism == CF_Dispatch) {
+ GuardFnName = "__guard_dispatch_icall_fptr";
} else {
- assert(GuardMechanism == CF_Dispatch && "Invalid CFGuard mechanism");
- GuardFnGlobal =
- M.getOrInsertGlobal("__guard_dispatch_icall_fptr", GuardFnPtrType);
+ assert("Invalid CFGuard mechanism");
}
+ GuardFnGlobal = M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
+ auto *Var = new GlobalVariable(M, GuardFnPtrType, false,
+ GlobalVariable::ExternalLinkage, nullptr,
+ GuardFnName);
+ Var->setDSOLocal(true);
+ return Var;
+ });
return true;
}
diff --git a/llvm/test/CodeGen/AArch64/cfguard-checks.ll b/llvm/test/CodeGen/AArch64/cfguard-checks.ll
index 3244f1dbedc1..53757fd75b69 100644
--- a/llvm/test/CodeGen/AArch64/cfguard-checks.ll
+++ b/llvm/test/CodeGen/AArch64/cfguard-checks.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=aarch64-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-w64-windows-gnu | FileCheck %s
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are correctly added when required.
diff --git a/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll b/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
index 8eb77b6adba3..735d5c2dcc99 100644
--- a/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
+++ b/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -mtriple=aarch64-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-w64-windows-gnu | FileCheck %s
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are not added in modules with the
diff --git a/llvm/test/CodeGen/ARM/cfguard-checks.ll b/llvm/test/CodeGen/ARM/cfguard-checks.ll
index 17928f0b8378..ed8bb78cd7c6 100644
--- a/llvm/test/CodeGen/ARM/cfguard-checks.ll
+++ b/llvm/test/CodeGen/ARM/cfguard-checks.ll
@@ -1,4 +1,5 @@
-; RUN: llc < %s -mtriple=arm-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=arm-pc-windows-msvc | FileCheck %s -check-prefixes=CHECK,MSVC
+; RUN: llc < %s -mtriple=arm-w64-windows-gnu | FileCheck %s -check-prefixes=CHECK,MINGW
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are correctly added when required.
@@ -99,7 +100,8 @@ lpad: ; preds = %entry
; CHECK: movt r4, :upper16:target_func
; CHECK: mov r0, r4
; CHECK: blx r1
- ; CHECK-NEXT: $Mtmp0:
+ ; MSVC-NEXT: $Mtmp0:
+ ; MINGW-NEXT: .Ltmp0:
; CHECK-NEXT: blx r4
; CHECK: @ %common.ret
; CHECK: @ %lpad
diff --git a/llvm/test/CodeGen/ARM/cfguard-module-flag.ll b/llvm/test/CodeGen/ARM/cfguard-module-flag.ll
index c8a4256ac522..4b6dedefc298 100644
--- a/llvm/test/CodeGen/ARM/cfguard-module-flag.ll
+++ b/llvm/test/CodeGen/ARM/cfguard-module-flag.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -mtriple=arm-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=arm-w64-windows-gnu | FileCheck %s
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are not added in modules with the
diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard-cast.ll b/llvm/test/CodeGen/WinCFGuard/cfguard-cast.ll
index e66345b0d70b..406248d107a2 100644
--- a/llvm/test/CodeGen/WinCFGuard/cfguard-cast.ll
+++ b/llvm/test/CodeGen/WinCFGuard/cfguard-cast.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s
; Check how constant function pointer casts are handled.
diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard-giats.ll b/llvm/test/CodeGen/WinCFGuard/cfguard-giats.ll
index 8d5ab6886ef3..655e30417845 100644
--- a/llvm/test/CodeGen/WinCFGuard/cfguard-giats.ll
+++ b/llvm/test/CodeGen/WinCFGuard/cfguard-giats.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s
; Control Flow Guard is currently only available on Windows
declare dllimport i32 @target_func1()
diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard-mingw.ll b/llvm/test/CodeGen/WinCFGuard/cfguard-mingw.ll
new file mode 100644
index 000000000000..085cde8c6169
--- /dev/null
+++ b/llvm/test/CodeGen/WinCFGuard/cfguard-mingw.ll
@@ -0,0 +1,228 @@
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s
+; Control Flow Guard is currently only available on Windows
+
+; This file was generated from the following source, using this command line:
+; clang++ -target x86_64-w64-windows-gnu cfguard-mingw.cpp -S -emit-llvm -o cfguard-mingw.ll -O -Xclang -cfguard
+;
+;-------------------------------------------------------------------------------
+; class __attribute__((dllexport)) Base {
+; public:
+; __attribute__((dllexport)) Base() = default;
+; __attribute__((dllexport)) virtual ~Base() = default;
+; __attribute__((dllexport)) virtual int calc() const {
+; return m_field * 2;
+; }
+; int m_field{0};
+; };
+;
+; class __attribute__((dllexport)) Derived : public Base {
+; public:
+; __attribute__((dllexport)) Derived() = default;
+; __attribute__((dllexport)) ~Derived() override = default;
+; __attribute__((dllexport)) int calc() const override {
+; return m_field * 2 + m_newfield;
+; }
+; int m_newfield{0};
+; };
+;
+; __attribute((noinline)) void address_taken() {}
+; __attribute((noinline)) void address_not_taken() {}
+;
+; using fn_t = void (*)();
+; __attribute__((dllexport)) fn_t get_address() {
+; address_not_taken();
+; return &address_taken;
+; }
+;-------------------------------------------------------------------------------
+
+; CHECK: .set @feat.00, 2048
+
+; CHECK: .section .gfids$y
+; CHECK: .symidx _ZNK7Derived4calcEv
+; CHECK: .symidx _Z13address_takenv
+
+; ModuleID = 'cfguard-mingw.cpp'
+source_filename = "cfguard-mingw.cpp"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-w64-windows-gnu"
+
+%class.Base = type <{ ptr, i32, [4 x i8] }>
+%class.Derived = type { %class.Base.base, i32 }
+%class.Base.base = type <{ ptr, i32 }>
+
+$_ZN4BaseC2Ev = comdat any
+
+$_ZN4BaseC1Ev = comdat any
+
+$_ZNK4Base4calcEv = comdat any
+
+$_ZN4BaseD2Ev = comdat any
+
+$_ZN4BaseD1Ev = comdat any
+
+$_ZN4BaseD0Ev = comdat any
+
+$_ZN7DerivedC2Ev = comdat any
+
+$_ZN7DerivedC1Ev = comdat any
+
+$_ZNK7Derived4calcEv = comdat any
+
+$_ZN7DerivedD2Ev = comdat any
+
+$_ZN7DerivedD1Ev = comdat any
+
+$_ZN7DerivedD0Ev = comdat any
+
+$_ZTV4Base = comdat any
+
+$_ZTV7Derived = comdat any
+
+$_ZTS4Base = comdat any
+
+$_ZTI4Base = comdat any
+
+$_ZTS7Derived = comdat any
+
+$_ZTI7Derived = comdat any
+
+ at _ZTV4Base = weak_odr dso_local dllexport unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI4Base, ptr @_ZN4BaseD1Ev, ptr @_ZN4BaseD0Ev, ptr @_ZNK4Base4calcEv] }, comdat, align 8
+ at _ZTV7Derived = weak_odr dso_local dllexport unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI7Derived, ptr @_ZN7DerivedD1Ev, ptr @_ZN7DerivedD0Ev, ptr @_ZNK7Derived4calcEv] }, comdat, align 8
+ at _ZTVN10__cxxabiv117__class_type_infoE = external global ptr
+ at _ZTS4Base = linkonce_odr dso_local constant [6 x i8] c"4Base\00", comdat, align 1
+ at _ZTI4Base = linkonce_odr dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS4Base }, comdat, align 8
+ at _ZTVN10__cxxabiv120__si_class_type_infoE = external global ptr
+ at _ZTS7Derived = linkonce_odr dso_local constant [9 x i8] c"7Derived\00", comdat, align 1
+ at _ZTI7Derived = linkonce_odr dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr @_ZTS7Derived, ptr @_ZTI4Base }, comdat, align 8
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN4BaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ store i32 0, ptr %2, align 8, !tbaa !8
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN4BaseC1Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ store i32 0, ptr %2, align 8, !tbaa !8
+ ret void
+}
+
+; Function Attrs: mustprogress nounwind uwtable
+define weak_odr dso_local dllexport noundef i32 @_ZNK4Base4calcEv(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #1 comdat align 2 {
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ %3 = load i32, ptr %2, align 8, !tbaa !8
+ %4 = shl nsw i32 %3, 1
+ ret i32 %4
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN4BaseD2Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN4BaseD1Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN4BaseD0Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
+ tail call void @_ZdlPv(ptr noundef nonnull %0) #5
+ ret void
+}
+
+; Function Attrs: nobuiltin nounwind
+declare dso_local void @_ZdlPv(ptr noundef) local_unnamed_addr #2
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN7DerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ store i32 0, ptr %2, align 8, !tbaa !8
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %3 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
+ store i32 0, ptr %3, align 4, !tbaa !12
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ store i32 0, ptr %2, align 8, !tbaa !8
+ store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
+ %3 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
+ store i32 0, ptr %3, align 4, !tbaa !12
+ ret void
+}
+
+; Function Attrs: mustprogress nounwind uwtable
+define weak_odr dso_local dllexport noundef i32 @_ZNK7Derived4calcEv(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #1 comdat align 2 {
+ %2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
+ %3 = load i32, ptr %2, align 8, !tbaa !8
+ %4 = shl nsw i32 %3, 1
+ %5 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
+ %6 = load i32, ptr %5, align 4, !tbaa !12
+ %7 = add nsw i32 %4, %6
+ ret i32 %7
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN7DerivedD2Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN7DerivedD1Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define weak_odr dso_local dllexport void @_ZN7DerivedD0Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
+ tail call void @_ZdlPv(ptr noundef nonnull %0) #5
+ ret void
+}
+
+; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable
+define dso_local void @_Z13address_takenv() #3 {
+ ret void
+}
+
+; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable
+define dso_local void @_Z17address_not_takenv() local_unnamed_addr #3 {
+ ret void
+}
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable
+define dso_local dllexport noundef nonnull ptr @_Z11get_addressv() local_unnamed_addr #4 {
+ ret ptr @_Z13address_takenv
+}
+
+attributes #0 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { mustprogress nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #2 = { nobuiltin nounwind "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #3 = { mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #4 = { mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #5 = { builtin nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 2, !"cfguard", i32 2}
+!1 = !{i32 1, !"wchar_size", i32 2}
+!2 = !{i32 8, !"PIC Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{!"clang version 16.0.0"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"vtable pointer", !7, i64 0}
+!7 = !{!"Simple C++ TBAA"}
+!8 = !{!9, !10, i64 8}
+!9 = !{!"_ZTS4Base", !10, i64 8}
+!10 = !{!"int", !11, i64 0}
+!11 = !{!"omnipotent char", !7, i64 0}
+!12 = !{!13, !10, i64 12}
+!13 = !{!"_ZTS7Derived", !9, i64 0, !10, i64 12}
diff --git a/llvm/test/CodeGen/X86/cfguard-checks-funclet.ll b/llvm/test/CodeGen/X86/cfguard-checks-funclet.ll
new file mode 100644
index 000000000000..8cf148f3d66a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/cfguard-checks-funclet.ll
@@ -0,0 +1,62 @@
+; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefixes=X64
+; Control Flow Guard is currently only available on Windows
+
+; funclets only supported in MSVC env.
+
+; Test that Control Flow Guard Checks are added well for targets in try-catch.
+
+
+declare i32 @target_func()
+
+
+%eh.ThrowInfo = type { i32, i8*, i8*, i8* }
+
+declare i32 @__CxxFrameHandler3(...)
+declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+
+define i32 @func_cf_exception() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ %func_ptr = alloca i32 ()*, align 8
+ store i32 ()* @target_func, i32 ()** %func_ptr, align 8
+ invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #11
+ to label %unreachable unwind label %ehcleanup
+
+ehcleanup:
+ %0 = cleanuppad within none []
+ %isnull = icmp eq i32 ()** %func_ptr, null
+ br i1 %isnull, label %exit, label %callfn
+
+callfn:
+ %1 = load i32 ()*, i32 ()** %func_ptr, align 8
+ %2 = call i32 %1() #9 [ "funclet"(token %0) ]
+ br label %exit
+
+exit:
+ cleanupret from %0 unwind label %catch.dispatch
+
+unreachable:
+ unreachable
+
+catch.dispatch:
+ %3 = catchswitch within none [label %catch] unwind to caller
+
+catch:
+ %4 = catchpad within %3 [i8* null, i32 64, i8* null]
+ catchret from %4 to label %try.cont
+
+try.cont:
+ ret i32 0
+
+ ; X32-LABEL: func_cf_exception
+ ; X32: calll *___guard_check_icall_fptr
+ ; X32-NEXT: calll *%ecx
+
+ ; X64-LABEL: func_cf_exception
+ ; X64: callq *__guard_dispatch_icall_fptr(%rip)
+ ; X64-NOT: callq
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"cfguard", i32 2}
diff --git a/llvm/test/CodeGen/X86/cfguard-checks.ll b/llvm/test/CodeGen/X86/cfguard-checks.ll
index b576cfa80637..7bcd9e84141d 100644
--- a/llvm/test/CodeGen/X86/cfguard-checks.ll
+++ b/llvm/test/CodeGen/X86/cfguard-checks.ll
@@ -1,5 +1,7 @@
; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
-; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefixes=X64,X64_MSVC
+; RUN: llc < %s -mtriple=i686-w64-windows-gnu | FileCheck %s -check-prefixes=X32,X32_MINGW
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s -check-prefixes=X64,X64_MINGW
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are correctly added when required.
@@ -105,6 +107,7 @@ lpad: ; preds = %entry
; X32: movl $_target_func, %esi
; X32: movl $_target_func, %ecx
; X32: calll *___guard_check_icall_fptr
+ ; X32_MINGW-NEXT: Ltmp0:
; X32-NEXT: calll *%esi
; X32: # %invoke.cont
; X32: # %lpad
@@ -143,12 +146,17 @@ entry:
; On x86_64, __guard_dispatch_icall_fptr tail calls the function, so there should be only one call instruction.
; X64-LABEL: func_cf_doubles
; X64: leaq target_func_doubles(%rip), %rax
- ; X64: movsd __real at 3ff0000000000000(%rip), %xmm0
- ; X64: movsd __real at 4000000000000000(%rip), %xmm1
- ; X64: movsd __real at 4008000000000000(%rip), %xmm2
- ; X64: movsd __real at 4010000000000000(%rip), %xmm3
+ ; X64_MSVC: movsd __real at 3ff0000000000000(%rip), %xmm0
+ ; X64_MSVC: movsd __real at 4000000000000000(%rip), %xmm1
+ ; X64_MSVC: movsd __real at 4008000000000000(%rip), %xmm2
+ ; X64_MSVC: movsd __real at 4010000000000000(%rip), %xmm3
+ ; X64_MINGW: movsd .LCPI4_0(%rip), %xmm0
+ ; X64_MINGW: movsd .LCPI4_1(%rip), %xmm1
+ ; X64_MINGW: movsd .LCPI4_2(%rip), %xmm2
+ ; X64_MINGW: movsd .LCPI4_3(%rip), %xmm3
; X64: callq *__guard_dispatch_icall_fptr(%rip)
; X64-NOT: callq
+
}
@@ -175,54 +183,6 @@ entry:
; X64-NOT: callq
}
-; Test that Control FLow Guard Checks are added well for targets in try-catch.
-%eh.ThrowInfo = type { i32, i8*, i8*, i8* }
-
-declare i32 @__CxxFrameHandler3(...)
-declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
-
-define i32 @func_cf_exception() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
- %func_ptr = alloca i32 ()*, align 8
- store i32 ()* @target_func, i32 ()** %func_ptr, align 8
- invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #11
- to label %unreachable unwind label %ehcleanup
-
-ehcleanup:
- %0 = cleanuppad within none []
- %isnull = icmp eq i32 ()** %func_ptr, null
- br i1 %isnull, label %exit, label %callfn
-
-callfn:
- %1 = load i32 ()*, i32 ()** %func_ptr, align 8
- %2 = call i32 %1() #9 [ "funclet"(token %0) ]
- br label %exit
-
-exit:
- cleanupret from %0 unwind label %catch.dispatch
-
-unreachable:
- unreachable
-
-catch.dispatch:
- %3 = catchswitch within none [label %catch] unwind to caller
-
-catch:
- %4 = catchpad within %3 [i8* null, i32 64, i8* null]
- catchret from %4 to label %try.cont
-
-try.cont:
- ret i32 0
-
- ; X32-LABEL: func_cf_exception
- ; X32: calll *___guard_check_icall_fptr
- ; X32-NEXT: calll *%ecx
-
- ; X64-LABEL: func_cf_exception
- ; X64: callq *__guard_dispatch_icall_fptr(%rip)
- ; X64-NOT: callq
-}
-
%struct.Foo = type { i32 (%struct.Foo*)** }
diff --git a/llvm/test/CodeGen/X86/cfguard-module-flag.ll b/llvm/test/CodeGen/X86/cfguard-module-flag.ll
index 94c99adcaae7..4675c641d5e2 100644
--- a/llvm/test/CodeGen/X86/cfguard-module-flag.ll
+++ b/llvm/test/CodeGen/X86/cfguard-module-flag.ll
@@ -1,6 +1,8 @@
; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefix=X64
+; RUN: llc < %s -mtriple=i686-w64-windows-gnu | FileCheck %s -check-prefix=X32
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s -check-prefix=X64
; Control Flow Guard is currently only available on Windows
; Test that Control Flow Guard checks are not added in modules with the
diff --git a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
index a2a24ba01832..fbba8f4bcaae 100644
--- a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
+++ b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s -check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s -check-prefix=X64
; Control Flow Guard is currently only available on Windows
diff --git a/llvm/test/CodeGen/X86/cfguard-x86-vectorcall.ll b/llvm/test/CodeGen/X86/cfguard-x86-vectorcall.ll
index 31938b76316f..ca5fe4f876d4 100644
--- a/llvm/test/CodeGen/X86/cfguard-x86-vectorcall.ll
+++ b/llvm/test/CodeGen/X86/cfguard-x86-vectorcall.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=i686-pc-windows-msvc | FileCheck %s -check-prefix=X32
+; RUN: llc < %s -mtriple=i686-w64-windows-gnu | FileCheck %s -check-prefix=X32
; Control Flow Guard is currently only available on Windows
More information about the llvm-commits
mailing list