erichkeane added a comment.

In D112349#3112315 <https://reviews.llvm.org/D112349#3112315>, @v.g.vassilev 
wrote:

> In D112349#3111927 <https://reviews.llvm.org/D112349#3111927>, @erichkeane 
> wrote:
>
>> In D112349#3111873 <https://reviews.llvm.org/D112349#3111873>, @ibookstein 
>> wrote:
>>
>>> And how is Cling expecting CFE to deal with partial knowledge situations at 
>>> the implementation level? To deal with exactly the non-local cases that the 
>>> current violations address?
>>> If there's no prescriptive way forward to dealing with these cases (so 
>>> they're tech debt without a remediation plan), then as far as I'm concerned 
>>> this case sits exactly under the same tech-debt umbrella of the existing 
>>> violations and the way forward is using the same violating solution for 
>>> this case too. 
>>> We definitely shouldn't block the IR verification indefinitely on this 
>>> impasse. Once an acceptable solution is found, this will also be part of 
>>> that refactor.
>>
>> My understanding is that the REPL setup is that the 'IR' just needs to be in 
>> a state where it doesn't require reverts/rewrites later, so that we can do 
>> partial-back-end-code-generation as we go along.  That said, I'm not 
>> positive as to the implications.  I'm just repeating the discussion the CFE 
>> code-owner made at the time.
>>
>> IMO, the 'acceptable' solution is to have a way to forward-declare an ifunc 
>> in IR so that we can fill in the resolver later on.  From your description 
>> earlier, it seems that this would work as we could emit it as an 'unknown 
>> symbol' (as if it was an undefined function declaration), and would be 
>> completely implementable in the CFE.
>>
>> So it would change your plan from earlier to:
>>
>> When processing cpu_specific, emit the ifunc "x.ifunc", with no resolver;
>> When processing cpu_dispatch:
>>
>>   Get/Create the ifunc, then pull up the resolver.
>>   If the resolver is null (as it should be), create one and update the 
>> 'ifunc'.
>>   Generate said resolver.
>>   
>
> Speaking of the incremental compilation case, we can experiment with the 
> clang-repl binary. I am not sure about the details of this discussion but 
> here is an example that works today:
>
>   llvm/build/bin/clang-repl 
>   clang-repl> __attribute__((cpu_specific(ivybridge))) void 
> single_version(void){}
>   clang-repl> void useage() {single_version();}
>   clang-repl> quit
>
> What would it be a good example to check if the incremental compilation case 
> is covered?

FWIW, the comments above are about not making it 'worse' at least/adding more wo

In D112349#3113054 <https://reviews.llvm.org/D112349#3113054>, @ibookstein 
wrote:

> I feel like we're getting lost in the weeds here.
>
> At the time a bitcode module is finalized, it is supposed to be in a valid 
> state. 
> The LLVM bitcode verifier does not consider GlobalAliases which have either a 
> null or an undefined aliasee to be valid. The same should have held for 
> GlobalIFuncs and their resolvers since their inception, and the fact that it 
> were not so is an oversight.
>
> There are two separate issues here which we need to decouple:
>
> - IFuncs with undefined resolvers were never valid, the verification just 
> happened to be missing. They also misbehave, as demonstrated by my example 
> above where a TU contains both cpu_specific and a usage, but no cpu_dispatch. 
> Therefore, we'd not be making anything worse by plugging the current hole in 
> the verification of GlobalIFunc and keeping cpu_specific/cpu_dispatch 
> working, using the same method we use to handle aliases or ifuncs that come 
> after declarations, i.e. cpu_specific emits plain function declarations, 
> cpu_dispatch upgrades them via takeName+RAUW+eraseFromParent if they already 
> exist. We'll have made the verification more robust, fixed a bug when there's 
> a TU where there's cpu_specific + usage but no cpu_dispatch, and not have 
> incurred more tech debt by doing so (since that tech debt already exists, and 
> a solution would need to address all these cases in exactly the same way).
> - Clang-repl/CGM needs infrastructure for dealing with this sort of 
> 'backtracking' in incremental compilation use-cases (declaration gets 
> upgraded to alias, declaration gets upgraded to ifunc). If it needs IR 
> changes for that, then they should be designed, agreed upon, and integrated. 
> We're not going to have a decision made in this closed PR discussion that 
> either GlobalAliases or GlobalIFuncs support a declaration state all of a 
> sudden. Such decisions could have cross-cutting ramifications in that there 
> would all of a sudden be 3 ways to represent things that are equivalent 
> to/get lowered to function declarations, rather than one. Limiting ourselves 
> to not using the existing solution for these use-cases/bugs in normal 
> compilation with the hope that it will ease the creation of a solution for 
> incremental compilation of the same use-cases is self-defeating.
>
> As for clang-repl, I've so far tried the following; I get the sense that I'm 
> poking around in less well-specified places (asserts and null-deref crashes):
>
>   itay ~/llvm-project/build (main)> bin/clang-repl
>   clang-repl> #include <stdio.h>
>   clang-repl> __attribute__((cpu_dispatch(generic))) void a(void);
>   clang-repl> __attribute__((cpu_specific(generic))) void a(void) { 
> puts("hi"); }
>   In file included from <<< inputs >>>:1:
>   input_line_2:1:55: warning: body of cpu_dispatch function will be ignored 
> [-Wfunction-multiversion]
>   __attribute__((cpu_specific(generic))) void a(void) { puts("hi"); }
>                                                         ^
>   clang-repl> auto b = (a(), 5);
>   clang-repl: 
> /home/itay/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1683: void 
> llvm::AsmPrinter::emitGlobalIFunc(llvm::Module &, const llvm::GlobalIFunc &): 
> Assertion `GI.hasLocalLinkage() && "Invalid ifunc linkage"' failed.
>   fish: 'bin/clang-repl' terminated by signal SIGABRT (Abort)
>   itay ~/llvm-project/build (main) [SIGABRT]> bin/clang-repl
>   clang-repl> extern int g_a __attribute__((alias("g_b")));
>   In file included from <<< inputs >>>:1:
>   input_line_0:1:31: error: alias must point to a defined variable or function
>   extern int g_a __attribute__((alias("g_b")));
>                                 ^
>   fish: 'bin/clang-repl' terminated by signal SIGSEGV (Address boundary error)
>   itay ~/llvm-project/build (main) [SIGSEGV]> bin/clang-repl
>   clang-repl> void foo(void) __attribute__((ifunc("foo_resolver")));
>   In file included from <<< inputs >>>:1:
>   input_line_1:1:31: error: ifunc must point to a defined function
>   void foo(void) __attribute__((ifunc("foo_resolver")));
>                                 ^
>   fish: 'bin/clang-repl' terminated by signal SIGSEGV (Address boundary error)
>   itay ~/llvm-project/build (main) [SIGSEGV]> bin/clang-repl
>   clang-repl> void foo(void);
>   clang-repl> void bar(void) __attribute__((alias("foo")));
>   In file included from <<< inputs >>>:1:
>   input_line_1:1:31: error: alias must point to a defined variable or function
>   void bar(void) __attribute__((alias("foo")));
>                                 ^
>   fish: 'bin/clang-repl' terminated by signal SIGSEGV (Address boundary error)
>   itay ~/llvm-project/build (main) [SIGSEGV]> bin/clang-repl
>   clang-repl> void foo(void); void bar(void) __attribute__((alias("foo"))); 
> void foo(void) {}
>   In file included from <<< inputs >>>:1:
>   input_line_0:1:47: error: alias must point to a defined variable or function
>   void foo(void); void bar(void) __attribute__((alias("foo"))); void 
> foo(void) {}
>                                                 ^
>   fish: 'bin/clang-repl' terminated by signal SIGSEGV (Address boundary error)
>   itay ~/llvm-project/build (main) [SIGSEGV]> bin/clang-repl
>   clang-repl> void foo(void) {}
>   clang-repl> void bar(void) __attribute__((alias("foo")));
>   In file included from <<< inputs >>>:1:
>   input_line_1:1:31: error: alias must point to a defined variable or function
>   void bar(void) __attribute__((alias("foo")));
>                                 ^
>   fish: 'bin/clang-repl' terminated by signal SIGSEGV (Address boundary error)

To me the 'not in the weeds' part is, "How do I get CPU-dispatch/CPU-specific 
to work without RAUW, since that is offensive to the CFE code owner?  
Additionally, I found that some of the examples without the defined resolver 
actually DO work in my downstream, though I don't know what changes we make to 
make that happen.  So adding this limitation in actually breaks my downstream.

> The LLVM bitcode verifier does not consider GlobalAliases which have either a 
> null or an undefined aliasee to be valid. The same should have held for 
> GlobalIFuncs and their resolvers since their inception, and the fact that it 
> were not so is an oversight.

Citation Needed here.  Is there a design document that specifies this, or is 
this your opinion?  If its the latter, the implementation was the 
documentation, so this is still a breaking change.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D112349

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

Reply via email to