[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-14 Thread Daniel Kiss via cfe-commits

DanielKristofKiss wrote:

test depends on the aarch64 backend in llvm.
// REQUIRES: aarch64-registered-target to be add to the test.

https://github.com/llvm/llvm-project/pull/116244

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-14 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`llvm-clang-x86_64-sie-ubuntu-fast` running on `sie-linux-worker` while 
building `clang,llvm` at step 6 "test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/144/builds/11605


Here is the relevant piece of the build log for the reference

```
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
 TEST 'Clang :: CodeGen/ifunc-win.c' FAILED 

Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang 
-cc1 -internal-isystem 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/20/include
 -nostdsysteminc -triple aarch64-pc-windows-msvc -emit-llvm -o - 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c
 | 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck
 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c
+ 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang 
-cc1 -internal-isystem 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/20/include
 -nostdsysteminc -triple aarch64-pc-windows-msvc -emit-llvm -o - 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c
+ 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck
 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c:46:11:
 error: CHECK: expected string not found in input
// CHECK: {{.*}} = internal{{.*}}global{{.*}}poison, align 8
  ^
:6:42: note: scanning from here
@global = dso_local global i32 0, align 4
 ^
:13:1: note: possible intended match here
define dso_local i32 @bar() #0 {
^
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c:58:11:
 error: CHECK: expected string not found in input
// CHECK: define internal void @{{.*}}()
  ^
:20:30: note: scanning from here
define dso_local void @bar2() #0 {
 ^
:39:1: note: possible intended match here
define internal ptr @foo_ifunc() #1 {
^

Input file: 
Check file: 
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c

-dump-input=help explains the following input dump.

Input was:
<<
1: ; ModuleID = 
'/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c'
 
2: source_filename = 
"/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/CodeGen/ifunc-win.c"
 
3: target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
 
4: target triple = 
"aarch64-pc-windows-msvc" 
5:  
6: @global = dso_local global i32 0, 
align 4 
check:45   ^
check:46'0  X error: 
no match found
7:  
check:46'0 ~
8: @foo = dso_local ifunc i32 (i32), 
ptr @foo_ifunc 
check:46'0 ~
9: @goo = dso_local ifunc void (), 
ptr @goo_ifunc 
check:46'0 ~~~
   10: @hoo = dso_local ifunc void (i32), 
ptr @hoo_ifunc 
check:46'0 ~~
...

```



https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-14 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss closed 
https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-13 Thread Jon Roelofs via cfe-commits

https://github.com/jroelofs approved this pull request.


https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-13 Thread Fangrui Song via cfe-commits

https://github.com/MaskRay approved this pull request.


https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-13 Thread Fangrui Song via cfe-commits


@@ -5796,12 +5796,18 @@ declared entity. The entity must not have weak linkage; 
for example, in C++,
 it cannot be applied to a declaration if a definition at that location would be
 considered inline.
 
-Not all targets support this attribute. ELF target support depends on both the
-linker and runtime linker, and is available in at least lld 4.0 and later,
-binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
-Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+Not all targets support this attribute:
+
+- ELF target support depends on both the linker and runtime linker, and is

MaskRay wrote:

I think we can drop the mention of lld here. lld 4.0 is not quite usable for a 
lot of issues/missing features.

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-13 Thread Alexandros Lamprineas via cfe-commits

labrinea wrote:

I'll let others approve since I am not a windows expert, but it looks okay from 
my end at least.

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-13 Thread Daniel Kiss via cfe-commits

DanielKristofKiss wrote:

ping

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-08 Thread Daniel Kiss via cfe-commits


@@ -5796,12 +5796,18 @@ declared entity. The entity must not have weak linkage; 
for example, in C++,
 it cannot be applied to a declaration if a definition at that location would be
 considered inline.
 
-Not all targets support this attribute. ELF target support depends on both the
-linker and runtime linker, and is available in at least lld 4.0 and later,
-binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
-Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+Not all targets support this attribute:
+
+- ELF target support depends on both the linker and runtime linker, and is

DanielKristofKiss wrote:

added, due to it works in the last few releases so deserves an entry.
https://godbolt.org/z/K5dY7qbjj 


https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-08 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss updated 
https://github.com/llvm/llvm-project/pull/111962

>From 122864160f098392c4afd1728eb924e7e26e70d9 Mon Sep 17 00:00:00 2001
From: Daniel Kiss 
Date: Tue, 8 Oct 2024 22:58:37 +0200
Subject: [PATCH 1/6] Add ifuncs support for Windows.

---
 clang/include/clang/Basic/Attr.td |  5 +-
 clang/include/clang/Basic/AttrDocs.td |  6 +-
 clang/include/clang/Basic/TargetInfo.h|  4 ++
 clang/test/CodeGen/attr-ifunc.c   |  4 +-
 clang/test/CodeGen/ifunc-win.c| 69 +++
 clang/test/CodeGen/ifunc.c|  5 ++
 .../Target/AArch64/AArch64TargetMachine.cpp   |  6 ++
 7 files changed, 95 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/ifunc-win.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+
+/// The ifunc is emitted before its resolver.
+int foo(int) __attribute__ ((ifunc("foo_ifunc")));
+
+static int f1(int i) {
+  return i + 1;
+}
+
+static int f2(int i)

[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-11-06 Thread Jon Roelofs via cfe-commits


@@ -5796,12 +5796,18 @@ declared entity. The entity must not have weak linkage; 
for example, in C++,
 it cannot be applied to a declaration if a definition at that location would be
 considered inline.
 
-Not all targets support this attribute. ELF target support depends on both the
-linker and runtime linker, and is available in at least lld 4.0 and later,
-binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
-Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+Not all targets support this attribute:
+
+- ELF target support depends on both the linker and runtime linker, and is

jroelofs wrote:

Pending the outcome of the other thread, you should mention baremetal avr here.

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-15 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss updated 
https://github.com/llvm/llvm-project/pull/111962

>From 122864160f098392c4afd1728eb924e7e26e70d9 Mon Sep 17 00:00:00 2001
From: Daniel Kiss 
Date: Tue, 8 Oct 2024 22:58:37 +0200
Subject: [PATCH 1/4] Add ifuncs support for Windows.

---
 clang/include/clang/Basic/Attr.td |  5 +-
 clang/include/clang/Basic/AttrDocs.td |  6 +-
 clang/include/clang/Basic/TargetInfo.h|  4 ++
 clang/test/CodeGen/attr-ifunc.c   |  4 +-
 clang/test/CodeGen/ifunc-win.c| 69 +++
 clang/test/CodeGen/ifunc.c|  5 ++
 .../Target/AArch64/AArch64TargetMachine.cpp   |  6 ++
 7 files changed, 95 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/ifunc-win.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+
+/// The ifunc is emitted before its resolver.
+int foo(int) __attribute__ ((ifunc("foo_ifunc")));
+
+static int f1(int i) {
+  return i + 1;
+}
+
+static int f2(int i)

[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Daniel Kiss via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s

DanielKristofKiss wrote:

So far, but other targets could be added here later without too much change to 
the test.

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Martin Storsjö via cfe-commits


@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)

mstorsjo wrote:

I noted the same, but it seems it's intentional.

One of the existing tests use ifuncs for an `avr-unknown-unknown` target (which 
is OS-less). Previously, ifunc was accepted for any `TargetELFOrMachO`, which I 
guess was true for `avr-unknown-unknown`. But now it's only accepted for 
targets that are accepted by the `supportsIFunc()` method, which only accept a 
few specific OSes on ELF.

On the other hand, it doesn't seem consistent, that for baremetal, ifunc is 
supported depending on the architecture - but this is needed to keep the 
existing tests passing at least.

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Alexandros Lamprineas via cfe-commits


@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)

labrinea wrote:

Is this an unrelated change?

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Alexandros Lamprineas via cfe-commits


@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s

labrinea wrote:

Is this test file specific to AArch64? If so is it worth adding an 'aarch64-' 
prefix to it?

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss edited 
https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-14 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss updated 
https://github.com/llvm/llvm-project/pull/111962

>From 122864160f098392c4afd1728eb924e7e26e70d9 Mon Sep 17 00:00:00 2001
From: Daniel Kiss 
Date: Tue, 8 Oct 2024 22:58:37 +0200
Subject: [PATCH 1/3] Add ifuncs support for Windows.

---
 clang/include/clang/Basic/Attr.td |  5 +-
 clang/include/clang/Basic/AttrDocs.td |  6 +-
 clang/include/clang/Basic/TargetInfo.h|  4 ++
 clang/test/CodeGen/attr-ifunc.c   |  4 +-
 clang/test/CodeGen/ifunc-win.c| 69 +++
 clang/test/CodeGen/ifunc.c|  5 ++
 .../Target/AArch64/AArch64TargetMachine.cpp   |  6 ++
 7 files changed, 95 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/ifunc-win.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+
+/// The ifunc is emitted before its resolver.
+int foo(int) __attribute__ ((ifunc("foo_ifunc")));
+
+static int f1(int i) {
+  return i + 1;
+}
+
+static int f2(int i)

[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-11 Thread Martin Storsjö via cfe-commits


@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on

mstorsjo wrote:

The sentence starting with "Windows on AArch64" feels like it's missing some 
word at the start, maybe it should start with "On Windows ..."?

https://github.com/llvm/llvm-project/pull/111962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Daniel Kiss (DanielKristofKiss)


Changes

On Windows there is no platform support for ifunc but we could lower them to 
global function pointers.
This also enables FMV for Windows with Clang and Compiler-rt.

Depends on #111961 and #111960

---
Full diff: https://github.com/llvm/llvm-project/pull/111962.diff


7 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+4-1) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+4-2) 
- (modified) clang/include/clang/Basic/TargetInfo.h (+4) 
- (modified) clang/test/CodeGen/attr-ifunc.c (+3-1) 
- (added) clang/test/CodeGen/ifunc-win.c (+69) 
- (modified) clang/test/CodeGen/ifunc.c (+5) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetMachine.cpp (+6) 


``diff
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+
+/// The ifunc is emitted before its resolver.
+int foo(int) __attribute__ ((ifunc("foo_ifunc")));
+
+static int f1(int i) {
+  return i + 1;
+}
+
+static int f2(in

[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-11 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-aarch64

Author: Daniel Kiss (DanielKristofKiss)


Changes

On Windows there is no platform support for ifunc but we could lower them to 
global function pointers.
This also enables FMV for Windows with Clang and Compiler-rt.

Depends on #111961 and #111960

---
Full diff: https://github.com/llvm/llvm-project/pull/111962.diff


7 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+4-1) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+4-2) 
- (modified) clang/include/clang/Basic/TargetInfo.h (+4) 
- (modified) clang/test/CodeGen/attr-ifunc.c (+3-1) 
- (added) clang/test/CodeGen/ifunc-win.c (+69) 
- (modified) clang/test/CodeGen/ifunc.c (+5) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetMachine.cpp (+6) 


``diff
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+
+/// The ifunc is emitted before its resolver.
+int foo(int) __attribute__ ((ifunc("foo_ifunc")));
+
+static int f1(int i) {
+  return i + 1;
+}
+
+static

[clang] [llvm] Add ifunc support for Windows on AArch64. (PR #111962)

2024-10-11 Thread Daniel Kiss via cfe-commits

https://github.com/DanielKristofKiss created 
https://github.com/llvm/llvm-project/pull/111962

On Windows there is no platform support for ifunc but we could lower them to 
global function pointers.
This also enables FMV for Windows with Clang and Compiler-rt.

Depends on #111961 and #111960

>From 122864160f098392c4afd1728eb924e7e26e70d9 Mon Sep 17 00:00:00 2001
From: Daniel Kiss 
Date: Tue, 8 Oct 2024 22:58:37 +0200
Subject: [PATCH] Add ifuncs support for Windows.

---
 clang/include/clang/Basic/Attr.td |  5 +-
 clang/include/clang/Basic/AttrDocs.td |  6 +-
 clang/include/clang/Basic/TargetInfo.h|  4 ++
 clang/test/CodeGen/attr-ifunc.c   |  4 +-
 clang/test/CodeGen/ifunc-win.c| 69 +++
 clang/test/CodeGen/ifunc.c|  5 ++
 .../Target/AArch64/AArch64TargetMachine.cpp   |  6 ++
 7 files changed, 95 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/ifunc-win.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index ec3d6e0079f630..c0a540d3890487 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
 def TargetELFOrMachO : TargetSpec {
   let ObjectFormats = ["ELF", "MachO"];
 }
+def TargetIFuncSupport : TargetSpec {
+  let CustomCode = [{ Target.supportsIFunc() }];
+}
 def TargetWindowsArm64EC : TargetSpec {
   let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
 }
@@ -1847,7 +1850,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr {
+def IFunc : Attr, TargetSpecificAttr {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b1512e22ee2dd4..5179f30400345d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,8 +5800,10 @@ Not all targets support this attribute. ELF target 
support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
 Mach-O targets support it, but with slightly different semantics: the resolver
-is run at first call, instead of at load time by the runtime linker. Targets
-other than ELF and Mach-O currently do not support this attribute.
+is run at first call, instead of at load time by the runtime linker. Windows on
+AArch64 the ``ifunc`` is replaced with global function pointer and the call is
+replaced by an indirect call. The pointer is initialized by a contructor that
+calls the resolver. Other targets currently do not support this attribute.
   }];
 }
 
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 57783850606290..9d2d7be7cfbd78 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1505,6 +1505,10 @@ class TargetInfo : public TransferrableTargetInfo,
   bool supportsIFunc() const {
 if (getTriple().isOSBinFormatMachO())
   return true;
+if (getTriple().isOSWindows() && getTriple().isAArch64())
+  return true;
+if (getTriple().getArch() == llvm::Triple::ArchType::avr)
+  return true;
 return getTriple().isOSBinFormatELF() &&
((getTriple().isOSLinux() && !getTriple().isMusl()) ||
 getTriple().isOSFreeBSD());
diff --git a/clang/test/CodeGen/attr-ifunc.c b/clang/test/CodeGen/attr-ifunc.c
index 24d66433ae090f..c9e70b17a83023 100644
--- a/clang/test/CodeGen/attr-ifunc.c
+++ b/clang/test/CodeGen/attr-ifunc.c
@@ -2,8 +2,10 @@
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only 
-DCHECK_ALIASES %s
 // RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvcu -verify -emit-llvm-only %s
 
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(__aarch64__)
 void foo(void) {}
 void bar(void) __attribute__((ifunc("foo")));
 // expected-warning@-1 {{unknown attribute 'ifunc' ignored}}
diff --git a/clang/test/CodeGen/ifunc-win.c b/clang/test/CodeGen/ifunc-win.c
new file mode 100644
index 00..d8a94df90fc603
--- /dev/null
+++ b/clang/test/CodeGen/ifunc-win.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -O2 -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=thread -O2 
-emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fsanitize=address -O2 
-emit-llvm -o - %s | FileChe