[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-10 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn marked 18 inline comments as done.
zsrkmyn added a comment.

All done IMO. :-)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-10 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn updated this revision to Diff 219568.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/attr-cpuspecific.c
  clang/test/CodeGen/attr-target-mv-func-ptrs.c
  clang/test/CodeGen/attr-target-mv-va-args.c
  clang/test/CodeGen/attr-target-mv.c
  clang/test/CodeGenCXX/attr-cpuspecific.cpp
  clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
  clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp
  clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
  clang/test/CodeGenCXX/attr-target-mv-modules.cpp
  clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
  clang/test/CodeGenCXX/attr-target-mv-overloads.cpp

Index: clang/test/CodeGenCXX/attr-target-mv-overloads.cpp
===
--- clang/test/CodeGenCXX/attr-target-mv-overloads.cpp
+++ clang/test/CodeGenCXX/attr-target-mv-overloads.cpp
@@ -14,8 +14,8 @@
   return foo_overload() + foo_overload(1);
 }
 
-// LINUX: @_Z12foo_overloadv.ifunc = ifunc i32 (), i32 ()* ()* @_Z12foo_overloadv.resolver
-// LINUX: @_Z12foo_overloadi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z12foo_overloadi.resolver
+// LINUX: @_Z12foo_overloadv.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @_Z12foo_overloadv.resolver
+// LINUX: @_Z12foo_overloadi.ifunc = weak_odr ifunc i32 (i32), i32 (i32)* ()* @_Z12foo_overloadi.resolver
 
 // LINUX: define i32 @_Z12foo_overloadi.sse4.2(i32 %0)
 // LINUX: ret i32 0
@@ -51,25 +51,25 @@
 // WINDOWS: call i32 @"?foo_overload@@YAHXZ.resolver"()
 // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.resolver"(i32 1)
 
-// LINUX: define i32 ()* @_Z12foo_overloadv.resolver() comdat
+// LINUX: define weak_odr i32 ()* @_Z12foo_overloadv.resolver() comdat
 // LINUX: ret i32 ()* @_Z12foo_overloadv.arch_sandybridge
 // LINUX: ret i32 ()* @_Z12foo_overloadv.arch_ivybridge
 // LINUX: ret i32 ()* @_Z12foo_overloadv.sse4.2
 // LINUX: ret i32 ()* @_Z12foo_overloadv
 
-// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat
+// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat
 // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge"
 // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge"
 // WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2"
 // WINDOWS: call i32 @"?foo_overload@@YAHXZ"
 
-// LINUX: define i32 (i32)* @_Z12foo_overloadi.resolver() comdat
+// LINUX: define weak_odr i32 (i32)* @_Z12foo_overloadi.resolver() comdat
 // LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_sandybridge
 // LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_ivybridge
 // LINUX: ret i32 (i32)* @_Z12foo_overloadi.sse4.2
 // LINUX: ret i32 (i32)* @_Z12foo_overloadi
 
-// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat
+// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat
 // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge"
 // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_ivybridge"
 // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2"
Index: clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
===
--- clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
+++ clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
@@ -16,7 +16,7 @@
   return s.foo(0);
 }
 
-// LINUX: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
+// LINUX: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
 
 // LINUX: define i32 @_ZN1S3fooEi(%struct.S* %this, i32 %0)
 // LINUX: ret i32 2
@@ -44,13 +44,13 @@
 // WINDOWS: %s = alloca %struct.S, align 1
 // WINDOWS: %call = call i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S* %s, i32 0)
 
-// LINUX: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
+// LINUX: define weak_odr i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
 // LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
 // LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
 // LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
 // LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
 
-// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S* %0, i32 %1) comdat
+// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(%struct.S* %0, i32 %1) comdat
 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S* %0, i32 %1)
 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %0, i32 %1)
 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %0, i32 %1)
Index: clang/test/CodeGenCXX/attr-target-mv-modules.cpp
===
--- clang/test/CodeGenCXX/attr-target-mv-modules.cpp
+++ clang/test/CodeGenCXX/attr-target-mv-modules.cpp
@@ -22,7 +22,7 @@
 void g() { f(); }
 
 // Negative tests to validate that the 

[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-10 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

erichkeane wrote:
> zsrkmyn wrote:
> > erichkeane wrote:
> > > zsrkmyn wrote:
> > > > erichkeane wrote:
> > > > > zsrkmyn wrote:
> > > > > > zsrkmyn wrote:
> > > > > > > erichkeane wrote:
> > > > > > > > zsrkmyn wrote:
> > > > > > > > > erichkeane wrote:
> > > > > > > > > > This Resolver should have the same linkage as below.
> > > > > > > > > Actually, I wanted to set linkage here at the first time, but 
> > > > > > > > > failed. When compiling code with cpu_specific but no 
> > > > > > > > > cpu_dispatch, we cannot set it as LinkOnceODR or WeakODR. 
> > > > > > > > > E.g.:
> > > > > > > > > 
> > > > > > > > > ```
> > > > > > > > > $ cat specific_only.c
> > > > > > > > > __declspec(cpu_specific(pentium_iii))
> > > > > > > > > int foo(void) { return 0; }
> > > > > > > > > int usage() { return foo(); }
> > > > > > > > > 
> > > > > > > > > $ clang -fdeclspec specific_only.c
> > > > > > > > >  
> > > > > > > > > Global is external, but doesn't have external or weak 
> > > > > > > > > linkage!  
> > > > > > > > >   
> > > > > > > > > i32 ()* ()* @foo.resolver 
> > > > > > > > >   
> > > > > > > > >   
> > > > > > > > > fatal error: error in backend: Broken module found, 
> > > > > > > > > compilation aborted!   
> > > > > > > > > ```
> > > > > > > > > 
> > > > > > > > > This is found by lit test test/CodeGen/attr-cpuspecific.c, in 
> > > > > > > > > which 'SingleVersion()' doesn't have a cpu_dispatch 
> > > > > > > > > declaration.
> > > > > > > > The crash message is complaining it isn't external/weak.  
> > > > > > > > However, WeakODR should count, right?  Can you look into it a 
> > > > > > > > bit more to see what it thinks is broken?
> > > > > > > No, actually I've tried it earlier with the example I mentioned 
> > > > > > > in my last comment, but WeakODR still makes compiler complaining. 
> > > > > > > I think it's `foo.resolver` that cannot be declared with as 
> > > > > > > WeakODR/LinkOnceODR without definition. But I'm really not 
> > > > > > > familiar with these rules.
> > > > > > According to the `Verifier::visitGlobalValue()` in Verify.cpp, an 
> > > > > > declaration can only be `ExternalLinkage` or `ExternalWeakLinkage`. 
> > > > > > So I still believe we cannot set the resolver to 
> > > > > > `LinkOnceODRLinkage/WeakODRLinkage` here, as they are declared but 
> > > > > > not defined when we only have `cpu_specified` but no `cpu_dispatch` 
> > > > > > in a TU as the example above.
> > > > > That doesn't seem right then.  IF it allows ExternalWeakLinkage I'd 
> > > > > expect WeakODR to work as well, since it is essentially the same 
> > > > > thing.
> > > > I think we should have a double check. It is said "It is illegal for a 
> > > > function declaration to have any linkage type other than `external` or 
> > > > `extern_weak`" at the last line of section Linkage Type in the 
> > > > reference manual [1]. I guess `weak_odr` is not designed for 
> > > > declaration purpose and should be only used by definition.
> > > > 
> > > > [1] https://llvm.org/docs/LangRef.html#linkage-types
> > > I had typed a reply, but apparently it didn't submit: Ah, nvm, I see now 
> > > that external-weak is different from weak.
> > > 
> > > I don't really get the linkages sufficiently to know what the right thing 
> > > to do is then.  If we DO have a definition, I'd say weak_odr so it can be 
> > > merged, right?  If we do NOT, could externally_available work?
> > No, I think it should be `external` instead of `available_externally`. The 
> > later cannot used for declaration as well.
> > 
> > So, getting back to the example, **1)** if we have `cpu_dispatch` and 
> > `cpu_specific` in same TU, it's okay to use `weak_odr` for `foo.resolver` 
> > as it is defined when `emitCPUDispatchDefinition` and it can be merged. 
> > **2)** If we only have `cpu_specific` in a TU and have a reference to the 
> > dispatched function, `foo.resolver` will be referenced without definition, 
> > and `external` is the proper linkage to make it work.
> > 
> > That's why I didn't set linkage type at this line.
> > No, I think it should be external instead of available_externally. The 
> > later cannot used for declaration as well.
> 
> Wouldn't that make it un-mergable later?  Meaning, if you emitted the 
> declaration from one TU, and the definition from another that you'd get a 
> link error?
> 
> I think the rules are more subtle than that.  Any time you have a 
> `cpu_dispatch`, the resolver is weak_odr so that it can be merged later.  The 
> presence of `cpu_specific` 

[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-10 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

erichkeane wrote:
> zsrkmyn wrote:
> > erichkeane wrote:
> > > zsrkmyn wrote:
> > > > zsrkmyn wrote:
> > > > > erichkeane wrote:
> > > > > > zsrkmyn wrote:
> > > > > > > erichkeane wrote:
> > > > > > > > This Resolver should have the same linkage as below.
> > > > > > > Actually, I wanted to set linkage here at the first time, but 
> > > > > > > failed. When compiling code with cpu_specific but no 
> > > > > > > cpu_dispatch, we cannot set it as LinkOnceODR or WeakODR. E.g.:
> > > > > > > 
> > > > > > > ```
> > > > > > > $ cat specific_only.c
> > > > > > > __declspec(cpu_specific(pentium_iii))
> > > > > > > int foo(void) { return 0; }
> > > > > > > int usage() { return foo(); }
> > > > > > > 
> > > > > > > $ clang -fdeclspec specific_only.c
> > > > > > >  
> > > > > > > Global is external, but doesn't have external or weak linkage!
> > > > > > > 
> > > > > > > i32 ()* ()* @foo.resolver 
> > > > > > > 
> > > > > > > fatal error: error in backend: Broken module found, compilation 
> > > > > > > aborted!   
> > > > > > > ```
> > > > > > > 
> > > > > > > This is found by lit test test/CodeGen/attr-cpuspecific.c, in 
> > > > > > > which 'SingleVersion()' doesn't have a cpu_dispatch declaration.
> > > > > > The crash message is complaining it isn't external/weak.  However, 
> > > > > > WeakODR should count, right?  Can you look into it a bit more to 
> > > > > > see what it thinks is broken?
> > > > > No, actually I've tried it earlier with the example I mentioned in my 
> > > > > last comment, but WeakODR still makes compiler complaining. I think 
> > > > > it's `foo.resolver` that cannot be declared with as 
> > > > > WeakODR/LinkOnceODR without definition. But I'm really not familiar 
> > > > > with these rules.
> > > > According to the `Verifier::visitGlobalValue()` in Verify.cpp, an 
> > > > declaration can only be `ExternalLinkage` or `ExternalWeakLinkage`. So 
> > > > I still believe we cannot set the resolver to 
> > > > `LinkOnceODRLinkage/WeakODRLinkage` here, as they are declared but not 
> > > > defined when we only have `cpu_specified` but no `cpu_dispatch` in a TU 
> > > > as the example above.
> > > That doesn't seem right then.  IF it allows ExternalWeakLinkage I'd 
> > > expect WeakODR to work as well, since it is essentially the same thing.
> > I think we should have a double check. It is said "It is illegal for a 
> > function declaration to have any linkage type other than `external` or 
> > `extern_weak`" at the last line of section Linkage Type in the reference 
> > manual [1]. I guess `weak_odr` is not designed for declaration purpose and 
> > should be only used by definition.
> > 
> > [1] https://llvm.org/docs/LangRef.html#linkage-types
> I had typed a reply, but apparently it didn't submit: Ah, nvm, I see now that 
> external-weak is different from weak.
> 
> I don't really get the linkages sufficiently to know what the right thing to 
> do is then.  If we DO have a definition, I'd say weak_odr so it can be 
> merged, right?  If we do NOT, could externally_available work?
No, I think it should be `external` instead of `available_externally`. The 
later cannot used for declaration as well.

So, getting back to the example, **1)** if we have `cpu_dispatch` and 
`cpu_specific` in same TU, it's okay to use `weak_odr` for `foo.resolver` as it 
is defined when `emitCPUDispatchDefinition` and it can be merged. **2)** If we 
only have `cpu_specific` in a TU and have a reference to the dispatched 
function, `foo.resolver` will be referenced without definition, and `external` 
is the proper linkage to make it work.

That's why I didn't set linkage type at this line.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-10 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

erichkeane wrote:
> zsrkmyn wrote:
> > zsrkmyn wrote:
> > > erichkeane wrote:
> > > > zsrkmyn wrote:
> > > > > erichkeane wrote:
> > > > > > This Resolver should have the same linkage as below.
> > > > > Actually, I wanted to set linkage here at the first time, but failed. 
> > > > > When compiling code with cpu_specific but no cpu_dispatch, we cannot 
> > > > > set it as LinkOnceODR or WeakODR. E.g.:
> > > > > 
> > > > > ```
> > > > > $ cat specific_only.c
> > > > > __declspec(cpu_specific(pentium_iii))
> > > > > int foo(void) { return 0; }
> > > > > int usage() { return foo(); }
> > > > > 
> > > > > $ clang -fdeclspec specific_only.c
> > > > >  
> > > > > Global is external, but doesn't have external or weak linkage!
> > > > > 
> > > > > i32 ()* ()* @foo.resolver 
> > > > > 
> > > > > fatal error: error in backend: Broken module found, compilation 
> > > > > aborted!   
> > > > > ```
> > > > > 
> > > > > This is found by lit test test/CodeGen/attr-cpuspecific.c, in which 
> > > > > 'SingleVersion()' doesn't have a cpu_dispatch declaration.
> > > > The crash message is complaining it isn't external/weak.  However, 
> > > > WeakODR should count, right?  Can you look into it a bit more to see 
> > > > what it thinks is broken?
> > > No, actually I've tried it earlier with the example I mentioned in my 
> > > last comment, but WeakODR still makes compiler complaining. I think it's 
> > > `foo.resolver` that cannot be declared with as WeakODR/LinkOnceODR 
> > > without definition. But I'm really not familiar with these rules.
> > According to the `Verifier::visitGlobalValue()` in Verify.cpp, an 
> > declaration can only be `ExternalLinkage` or `ExternalWeakLinkage`. So I 
> > still believe we cannot set the resolver to 
> > `LinkOnceODRLinkage/WeakODRLinkage` here, as they are declared but not 
> > defined when we only have `cpu_specified` but no `cpu_dispatch` in a TU as 
> > the example above.
> That doesn't seem right then.  IF it allows ExternalWeakLinkage I'd expect 
> WeakODR to work as well, since it is essentially the same thing.
I think we should have a double check. It is said "It is illegal for a function 
declaration to have any linkage type other than `external` or `extern_weak`" at 
the last line of section Linkage Type in the reference manual [1]. I guess 
`weak_odr` is not designed for declaration purpose and should be only used by 
definition.

[1] https://llvm.org/docs/LangRef.html#linkage-types


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-07 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn marked an inline comment as done.
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

zsrkmyn wrote:
> erichkeane wrote:
> > zsrkmyn wrote:
> > > erichkeane wrote:
> > > > This Resolver should have the same linkage as below.
> > > Actually, I wanted to set linkage here at the first time, but failed. 
> > > When compiling code with cpu_specific but no cpu_dispatch, we cannot set 
> > > it as LinkOnceODR or WeakODR. E.g.:
> > > 
> > > ```
> > > $ cat specific_only.c
> > > __declspec(cpu_specific(pentium_iii))
> > > int foo(void) { return 0; }
> > > int usage() { return foo(); }
> > > 
> > > $ clang -fdeclspec specific_only.c
> > >  
> > > Global is external, but doesn't have external or weak linkage!
> > > 
> > > i32 ()* ()* @foo.resolver 
> > > 
> > > fatal error: error in backend: Broken module found, compilation aborted!  
> > >  
> > > ```
> > > 
> > > This is found by lit test test/CodeGen/attr-cpuspecific.c, in which 
> > > 'SingleVersion()' doesn't have a cpu_dispatch declaration.
> > The crash message is complaining it isn't external/weak.  However, WeakODR 
> > should count, right?  Can you look into it a bit more to see what it thinks 
> > is broken?
> No, actually I've tried it earlier with the example I mentioned in my last 
> comment, but WeakODR still makes compiler complaining. I think it's 
> `foo.resolver` that cannot be declared with as WeakODR/LinkOnceODR without 
> definition. But I'm really not familiar with these rules.
According to the `Verifier::visitGlobalValue()` in Verify.cpp, an declaration 
can only be `ExternalLinkage` or `ExternalWeakLinkage`. So I still believe we 
cannot set the resolver to `LinkOnceODRLinkage/WeakODRLinkage` here, as they 
are declared but not defined when we only have `cpu_specified` but no 
`cpu_dispatch` in a TU as the example above.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-06 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn marked an inline comment as done.
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

erichkeane wrote:
> zsrkmyn wrote:
> > erichkeane wrote:
> > > This Resolver should have the same linkage as below.
> > Actually, I wanted to set linkage here at the first time, but failed. When 
> > compiling code with cpu_specific but no cpu_dispatch, we cannot set it as 
> > LinkOnceODR or WeakODR. E.g.:
> > 
> > ```
> > $ cat specific_only.c
> > __declspec(cpu_specific(pentium_iii))
> > int foo(void) { return 0; }
> > int usage() { return foo(); }
> > 
> > $ clang -fdeclspec specific_only.c  
> >
> > Global is external, but doesn't have external or weak linkage!  
> >   
> > i32 ()* ()* @foo.resolver   
> >   
> > fatal error: error in backend: Broken module found, compilation aborted!   
> > ```
> > 
> > This is found by lit test test/CodeGen/attr-cpuspecific.c, in which 
> > 'SingleVersion()' doesn't have a cpu_dispatch declaration.
> The crash message is complaining it isn't external/weak.  However, WeakODR 
> should count, right?  Can you look into it a bit more to see what it thinks 
> is broken?
No, actually I've tried it earlier with the example I mentioned in my last 
comment, but WeakODR still makes compiler complaining. I think it's 
`foo.resolver` that cannot be declared with as WeakODR/LinkOnceODR without 
definition. But I'm really not familiar with these rules.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-05 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn marked an inline comment as done.
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3005
 /*ForVTable=*/false);
+auto Linkage = (FD->isCPUDispatchMultiVersion() || 
FD->isCPUSpecificMultiVersion())
+? llvm::Function::LinkOnceODRLinkage

erichkeane wrote:
> I think this can always just be LinkOnceODR.
Changing this also changes linkage for attribute(target()), should I also 
change test cases for them? (including test/CodeGen{,CXX}/attr-*.ll)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-05 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3002
 false);
 llvm::Constant *Resolver = GetOrCreateLLVMFunction(
 MangledName + ".resolver", ResolverType, GlobalDecl{},

erichkeane wrote:
> This Resolver should have the same linkage as below.
Actually, I wanted to set linkage here at the first time, but failed. When 
compiling code with cpu_specific but no cpu_dispatch, we cannot set it as 
LinkOnceODR or WeakODR. E.g.:

```
$ cat specific_only.c
__declspec(cpu_specific(pentium_iii))
int foo(void) { return 0; }
int usage() { return foo(); }

$ clang -fdeclspec specific_only.c  
   
Global is external, but doesn't have external or weak linkage!  
  
i32 ()* ()* @foo.resolver   
  
fatal error: error in backend: Broken module found, compilation aborted!   
```

This is found by lit test test/CodeGen/attr-cpuspecific.c, in which 
'SingleVersion()' doesn't have a cpu_dispatch declaration.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type

2019-09-04 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn updated this revision to Diff 218830.
zsrkmyn retitled this revision from "[clang][CodeGen] Add alias for 
cpu_dispatch function with IFunc" to "[clang][CodeGen] Add alias for 
cpu_dispatch function with IFunc & Fix resolver linkage type".

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/attr-cpuspecific.c
  clang/test/CodeGenCXX/attr-cpuspecific.cpp

Index: clang/test/CodeGenCXX/attr-cpuspecific.cpp
===
--- clang/test/CodeGenCXX/attr-cpuspecific.cpp
+++ clang/test/CodeGenCXX/attr-cpuspecific.cpp
@@ -13,13 +13,15 @@
   s.Func();
 }
 
-// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
+// LINUX: @_ZN1S4FuncEv = linkonce_odr alias void (%struct.S*), void (%struct.S*)* @_ZN1S4FuncEv.ifunc
+// LINUX: @_ZN1S4FuncEv.ifunc = linkonce_odr ifunc void (%struct.S*), void (%struct.S*)* ()* @_ZN1S4FuncEv.resolver
+// LINUX: define linkonce_odr void (%struct.S*)* @_ZN1S4FuncEv.resolver
 // LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
 // LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
 // LINUX: declare void @_ZN1S4FuncEv.S
 // LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
 
-// WINDOWS: define dso_local void @"?Func@S@@QEAAXXZ"(%struct.S* %0)
+// WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ"(%struct.S* %0) comdat
 // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(%struct.S* %0)
 // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(%struct.S* %0)
 // WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S"
Index: clang/test/CodeGen/attr-cpuspecific.c
===
--- clang/test/CodeGen/attr-cpuspecific.c
+++ clang/test/CodeGen/attr-cpuspecific.c
@@ -7,11 +7,27 @@
 #define ATTR(X) __attribute__((X))
 #endif // _MSC_VER
 
-// Each called version should have an IFunc.
-// LINUX: @SingleVersion.ifunc = ifunc void (), void ()* ()* @SingleVersion.resolver
-// LINUX: @TwoVersions.ifunc = ifunc void (), void ()* ()* @TwoVersions.resolver
-// LINUX: @TwoVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver
-// LINUX: @ThreeVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver
+// Each version should have an IFunc and an alias.
+// LINUX: @TwoVersions = linkonce_odr alias void (), void ()* @TwoVersions.ifunc
+// LINUX: @TwoVersionsSameAttr = linkonce_odr alias void (), void ()* @TwoVersionsSameAttr.ifunc
+// LINUX: @ThreeVersionsSameAttr = linkonce_odr alias void (), void ()* @ThreeVersionsSameAttr.ifunc
+// LINUX: @NoSpecifics = linkonce_odr alias void (), void ()* @NoSpecifics.ifunc
+// LINUX: @HasGeneric = linkonce_odr alias void (), void ()* @HasGeneric.ifunc
+// LINUX: @HasParams = linkonce_odr alias void (i32, double), void (i32, double)* @HasParams.ifunc
+// LINUX: @HasParamsAndReturn = linkonce_odr alias i32 (i32, double), i32 (i32, double)* @HasParamsAndReturn.ifunc
+// LINUX: @GenericAndPentium = linkonce_odr alias i32 (i32, double), i32 (i32, double)* @GenericAndPentium.ifunc
+// LINUX: @DispatchFirst = linkonce_odr alias i32 (), i32 ()* @DispatchFirst.ifunc
+
+// LINUX: @TwoVersions.ifunc = linkonce_odr ifunc void (), void ()* ()* @TwoVersions.resolver
+// LINUX: @SingleVersion.ifunc = linkonce_odr ifunc void (), void ()* ()* @SingleVersion.resolver
+// LINUX: @TwoVersionsSameAttr.ifunc = linkonce_odr ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver
+// LINUX: @ThreeVersionsSameAttr.ifunc = linkonce_odr ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver
+// LINUX: @NoSpecifics.ifunc = linkonce_odr ifunc void (), void ()* ()* @NoSpecifics.resolver
+// LINUX: @HasGeneric.ifunc = linkonce_odr ifunc void (), void ()* ()* @HasGeneric.resolver
+// LINUX: @HasParams.ifunc = linkonce_odr ifunc void (i32, double), void (i32, double)* ()* @HasParams.resolver
+// LINUX: @HasParamsAndReturn.ifunc = linkonce_odr ifunc i32 (i32, double), i32 (i32, double)* ()* @HasParamsAndReturn.resolver
+// LINUX: @GenericAndPentium.ifunc = linkonce_odr ifunc i32 (i32, double), i32 (i32, double)* ()* @GenericAndPentium.resolver
+// LINUX: @DispatchFirst.ifunc = linkonce_odr ifunc i32 (), i32 ()* ()* @DispatchFirst.resolver
 
 ATTR(cpu_specific(ivybridge))
 void SingleVersion(void){}
@@ -29,14 +45,14 @@
 
 ATTR(cpu_dispatch(ivybridge, knl))
 void TwoVersions(void);
-// LINUX: define void ()* @TwoVersions.resolver()
+// LINUX: define linkonce_odr void ()* @TwoVersions.resolver()
 // LINUX: call void @__cpu_indicator_init
 // LINUX: ret void ()* @TwoVersions.Z
 // LINUX: ret void ()* @TwoVersions.S
 // LINUX: call void @llvm.trap
 // LINUX: unreachable
 
-// WINDOWS: define dso_local void @TwoVersions()
+// WINDOWS: define linkonce_odr dso_local void @TwoVersions() comdat
 // WINDOWS: call void @__cpu_indicator_init()
 // WINDOWS: call void @TwoVersions.Z()
 // WINDOWS-NEXT: ret void
@@ -82,14 +98,14 @@
 

[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc

2019-09-04 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:2957
+if (!AliasFunc) {
+  auto *IFunc = cast(GetOrCreateLLVMFunction(
+  AliasName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,

erichkeane wrote:
> erichkeane wrote:
> > zsrkmyn wrote:
> > > erichkeane wrote:
> > > > erichkeane wrote:
> > > > > I think we want this in GetOrCreateMultiVersionResolver, so that it 
> > > > > gets created when the ifunc does.  That way you just need a 
> > > > > "FD->isCPUDispatchMultiVersion() || isCPUSpecificMultiVersion()" 
> > > > > check inside the supportsIFunc branch.
> > > > After discussing this offline, I believe this is the right function to 
> > > > create the alias.  The motivating example is:
> > > > 
> > > > // TU1:
> > > > __attribute__((cpu_dispatch(a,b,c))) void foo(void);
> > > > 
> > > > // TU2:
> > > > extern void foo(void);
> > > > 
> > > > Currently, TU1 doesn't bother to emit the ifunc, because we've attached 
> > > > emitting this to when this is referenced.
> > > > 
> > > > We made that choice because we expected TU2 to mark 'foo' as 
> > > > cpu_dispatch/cpu_specific in SOME way.  I believe that it is harmless 
> > > > to emit the ifunc all the time, which this is attempting to do.  
> > > > However, this needs to change the ifunc to have LinkOnceODR linkage in 
> > > > GetOrCreateMultiVersionResolver, otherwise this can cause linker errors.
> > > > 
> > > > 
> > > I've finished most parts. But I think we should also set the resolver to 
> > > have LinkOnceODR Linkage. Otherwise, we cannot have the cpu_dispatch 
> > > declaration in multiple TUs.
> > > 
> > > However there's no 'weak' symbol on Windows, so even setting the resolver 
> > > linkage to LinkOnceODR cannot solve the duplicate defined symbol problem 
> > > on Windows. Do you have any suggestions on it? :-)
> > Yep, I think the resolver should also be linkonceodr (as well as the 
> > ifunc).  See where they are generated and do it there.
> > 
> > I can't help but think that we've solved the weak symbols issue with 
> > windows before, but I cannot for the life of me remember.  @rnk  
> > @lebedev.ri , do either of you remember?  Does LinkOnceODR not do that 
> > trickery?
> There must be SOME solution for it, since otherwise inline functions wouldn't 
> work.  For example:
> 
> https://godbolt.org/z/RjB9Xb
> 
> Its totally permissible to define and use 'foo::bar' in multiple TUs.  Note 
> that it is marked linkonce_odr dso_local and comdat.  I'm not sure what the 
> latter two do, but please experiment and see which will allow the symbol to 
> be merged in the linker.
Thanks Erich! Yes, It's the comdat that does the trick. I'll update the patch 
later. https://llvm.org/docs/LangRef.html#comdats


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc

2019-09-04 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:2957
+if (!AliasFunc) {
+  auto *IFunc = cast(GetOrCreateLLVMFunction(
+  AliasName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,

erichkeane wrote:
> erichkeane wrote:
> > I think we want this in GetOrCreateMultiVersionResolver, so that it gets 
> > created when the ifunc does.  That way you just need a 
> > "FD->isCPUDispatchMultiVersion() || isCPUSpecificMultiVersion()" check 
> > inside the supportsIFunc branch.
> After discussing this offline, I believe this is the right function to create 
> the alias.  The motivating example is:
> 
> // TU1:
> __attribute__((cpu_dispatch(a,b,c))) void foo(void);
> 
> // TU2:
> extern void foo(void);
> 
> Currently, TU1 doesn't bother to emit the ifunc, because we've attached 
> emitting this to when this is referenced.
> 
> We made that choice because we expected TU2 to mark 'foo' as 
> cpu_dispatch/cpu_specific in SOME way.  I believe that it is harmless to emit 
> the ifunc all the time, which this is attempting to do.  However, this needs 
> to change the ifunc to have LinkOnceODR linkage in 
> GetOrCreateMultiVersionResolver, otherwise this can cause linker errors.
> 
> 
I've finished most parts. But I think we should also set the resolver to have 
LinkOnceODR Linkage. Otherwise, we cannot have the cpu_dispatch declaration in 
multiple TUs.

However there's no 'weak' symbol on Windows, so even setting the resolver 
linkage to LinkOnceODR cannot solve the duplicate defined symbol problem on 
Windows. Do you have any suggestions on it? :-)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc

2019-09-02 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn added a comment.

Thanks @lebedev.ri , I'm currently under discussion with @erichkeane  , and 
I'll add lit test after the final decision on how to solve the issue.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67058/new/

https://reviews.llvm.org/D67058



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67058: [clang][CodeGen] Add alias for cpu_dispatch function with IFunc

2019-09-01 Thread Sr.Zhang via Phabricator via cfe-commits
zsrkmyn created this revision.
zsrkmyn added a reviewer: erichkeane.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Multi-versioned functions defined by cpu_dispatch and implemented with IFunc
can not be called outside the translation units where they are defined due to
lack of symbols. This patch add function aliases for these functions and thus
make them visible outside.


Repository:
  rC Clang

https://reviews.llvm.org/D67058

Files:
  clang/lib/CodeGen/CodeGenModule.cpp


Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2948,6 +2948,25 @@
 
   CodeGenFunction CGF(*this);
   CGF.EmitMultiVersionResolver(ResolverFunc, Options);
+
+  if (getTarget().supportsIFunc()) {
+std::string AliasName = getMangledNameImpl(
+*this, GD, FD, /*OmitMultiVersionMangling=*/true);
+llvm::Constant *AliasFunc = GetGlobalValue(AliasName);
+if (!AliasFunc) {
+  auto *IFunc = cast(GetOrCreateLLVMFunction(
+  AliasName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,
+  /*IsThunk=*/false, llvm::AttributeList(), NotForDefinition));
+  auto *GA = llvm::GlobalAlias::create(
+ DeclTy, 0, getFunctionLinkage(GD), AliasName, IFunc, ());
+  const auto *D = GD.getDecl();
+  if (D->hasAttr() || D->hasAttr() ||
+  D->isWeakImported()) {
+GA->setLinkage(llvm::Function::WeakAnyLinkage);
+  }
+  SetCommonAttributes(GD, GA);
+}
+  }
 }
 
 /// If a dispatcher for the specified mangled name is not in the module, create


Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2948,6 +2948,25 @@
 
   CodeGenFunction CGF(*this);
   CGF.EmitMultiVersionResolver(ResolverFunc, Options);
+
+  if (getTarget().supportsIFunc()) {
+std::string AliasName = getMangledNameImpl(
+*this, GD, FD, /*OmitMultiVersionMangling=*/true);
+llvm::Constant *AliasFunc = GetGlobalValue(AliasName);
+if (!AliasFunc) {
+  auto *IFunc = cast(GetOrCreateLLVMFunction(
+  AliasName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,
+  /*IsThunk=*/false, llvm::AttributeList(), NotForDefinition));
+  auto *GA = llvm::GlobalAlias::create(
+ DeclTy, 0, getFunctionLinkage(GD), AliasName, IFunc, ());
+  const auto *D = GD.getDecl();
+  if (D->hasAttr() || D->hasAttr() ||
+  D->isWeakImported()) {
+GA->setLinkage(llvm::Function::WeakAnyLinkage);
+  }
+  SetCommonAttributes(GD, GA);
+}
+  }
 }
 
 /// If a dispatcher for the specified mangled name is not in the module, create
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits