Xinliang David Li via llvm-dev
2017-Oct-27 18:10 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
On Fri, Oct 27, 2017 at 1:50 AM, David Chisnall via llvm-dev < llvm-dev at lists.llvm.org> wrote:> This seems slightly inverted. As I understand it, the root of the problem > is that some standards, such as C, C++, and POSIX, define some functions as > special and we rely on their specialness when optimising. Unfortunately, > the specialness is a property of the source language and, possibly, > environment and not necessarily of the target. The knowledge of which > functions are special seems like it ought to belong in the front end, so a > C++ compiler might tag a function called _Znwm as special, but to a C or > Fortran front end this is just another function and shouldn’t be treated > specially. > > Would it not be cleaner to have the front end (and any optimisations that > are aware of special behaviour of functions) add metadata indicating that > these functions are special?Ideally many of these functions should be annotated as builtin in the system headers. An hacky solution is for frontend to check if the declarations are from system headers to decide if metadata needs to be applied. David> If the metadata is lost, then this inhibits later optimisations but > shouldn’t affect the semantics of the code (it’s always valid to treat the > special functions as non-special functions) and optimisations then don’t > need to mark them. This would also give us a free mechanism of specifying > functions that are semantically equivalent but have different spellings. > >> David > > > On 27 Oct 2017, at 04:14, Chandler Carruth via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > I've gotten a fantastic bug report. Consider the LLVM IR: > > > > target triple = "x86_64-unknown-linux-gnu" > > > > define internal i8* @access({ i8* }* %arg, i64) { > > ret i8* undef > > } > > > > define i8* @g({ i8* }* %arg) { > > bb: > > %tmp = alloca { i8* }*, align 8 > > store { i8* }* %arg, { i8* }** %tmp, align 8 > > br i1 undef, label %bb4, label %bb1 > > > > bb1: > > %tmp2 = load { i8* }*, { i8* }** %tmp, align 8 > > %tmp3 = call i8* @access({ i8* }* %tmp2, i64 undef) > > br label %bb4 > > > > bb4: > > ret i8* undef > > } > > > > This IR, if compiled with `opt -passes='cgscc(inline,argpromotion)' > -disable-output` hits a bunch of asserts in the LazyCallGraph. > > > > The problem here is that `argpromotion` turns a normal looking function > `i8* @access({ i8* }* %arg, i64)` and turn it into a magical function `i8* > @access(i8* %arg, i64)`. This latter signature is the POSIX `access` > function that LLVM's `TargetLibraryInfo` knows magical things about. > > > > Because *some* library functions known to `TargetLibraryInfo` can have > *calls* to them introduced at arbitrary points of optimization (consider > vectorized variants of math functions), the new pass manager and its graph > to provide ordering over the module get Very Unhappy when you *introduce* a > definition of a library function in the middle of the compilation pipeline. > > > > And really, we do *not* want `argpromotion` to do this. We don't want it > to turn some random function by the name of `@free` into the actual `@free` > function and suddenly change how LLVM handles it. > > > > So what do we do? > > > > One option is to make `argpromotion` and every other pass that mutates a > function's signature rename the function (or add a `nobuiltin` attribute to > it). However, this seems brittle and somewhat complicated. > > > > My proposal is that we admit that certain names of functions are > reserved in LLVM's IR. For these names, in some cases *any* function with > that name will be treated specially by the optimizer. We can still check > the signatures when transforming code based on LLVM's semantic > understanding of that function, but this avoids any need to check things > when mutating the signature of the function. > > > > This would require frontends to avoid emitting functions by these names > unless they should have these special semantics. However, even if they do, > everything should remain conservatively correct. But I'll send an email to > cfe-dev suggesting that Clang start "mangling" internal functions that > collide with target names. I think this is important as I've found a quite > surprising number of cases where this happens in real code. > > > > There is no need to auto-upgrade here, because again, LLVM's handling > will remain conservatively correct. > > > > Does this seem reasonable? If so, I'll send patches to update the > LangRef with these restrictions. I'll also take a quick stab at generating > some example tables of such names from the .td files used by > `TargetLibraryInfo` already. These can't be authoritative because of the > platform-specific nature of it, but should help people understand how this > area works. > > > > > > One alternative that seems appealing but doesn't actually help would be > to make `TargetLibraryInfo` ignore internal functions. That is how the C++ > spec seems to handle this for example (C library function names are > reserved only when they have linkage). But this doesn't work well for LLVM > because we want to be able to LTO an internalized C library. So I think we > need the rule for LLVM function names to not rely on linkage here. > > > > > > Thanks, > > -Chandler > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/18798603/attachment.html>
Robinson, Paul via llvm-dev
2017-Oct-27 18:15 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
+1 to what the Davids said. This could also help address the situation that the Android keynote mentioned at last week's dev meeting: if you're building the implementation of the library you don't want the compiler to wave its magic wand because it knows better than you. --paulr From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Xinliang David Li via llvm-dev Sent: Friday, October 27, 2017 11:11 AM To: David Chisnall Cc: llvm-dev Subject: Re: [llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM On Fri, Oct 27, 2017 at 1:50 AM, David Chisnall via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: This seems slightly inverted. As I understand it, the root of the problem is that some standards, such as C, C++, and POSIX, define some functions as special and we rely on their specialness when optimising. Unfortunately, the specialness is a property of the source language and, possibly, environment and not necessarily of the target. The knowledge of which functions are special seems like it ought to belong in the front end, so a C++ compiler might tag a function called _Znwm as special, but to a C or Fortran front end this is just another function and shouldn’t be treated specially. Would it not be cleaner to have the front end (and any optimisations that are aware of special behaviour of functions) add metadata indicating that these functions are special? Ideally many of these functions should be annotated as builtin in the system headers. An hacky solution is for frontend to check if the declarations are from system headers to decide if metadata needs to be applied. David If the metadata is lost, then this inhibits later optimisations but shouldn’t affect the semantics of the code (it’s always valid to treat the special functions as non-special functions) and optimisations then don’t need to mark them. This would also give us a free mechanism of specifying functions that are semantically equivalent but have different spellings. David> On 27 Oct 2017, at 04:14, Chandler Carruth via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: > > I've gotten a fantastic bug report. Consider the LLVM IR: > > target triple = "x86_64-unknown-linux-gnu" > > define internal i8* @access({ i8* }* %arg, i64) { > ret i8* undef > } > > define i8* @g({ i8* }* %arg) { > bb: > %tmp = alloca { i8* }*, align 8 > store { i8* }* %arg, { i8* }** %tmp, align 8 > br i1 undef, label %bb4, label %bb1 > > bb1: > %tmp2 = load { i8* }*, { i8* }** %tmp, align 8 > %tmp3 = call i8* @access({ i8* }* %tmp2, i64 undef) > br label %bb4 > > bb4: > ret i8* undef > } > > This IR, if compiled with `opt -passes='cgscc(inline,argpromotion)' -disable-output` hits a bunch of asserts in the LazyCallGraph. > > The problem here is that `argpromotion` turns a normal looking function `i8* @access({ i8* }* %arg, i64)` and turn it into a magical function `i8* @access(i8* %arg, i64)`. This latter signature is the POSIX `access` function that LLVM's `TargetLibraryInfo` knows magical things about. > > Because *some* library functions known to `TargetLibraryInfo` can have *calls* to them introduced at arbitrary points of optimization (consider vectorized variants of math functions), the new pass manager and its graph to provide ordering over the module get Very Unhappy when you *introduce* a definition of a library function in the middle of the compilation pipeline. > > And really, we do *not* want `argpromotion` to do this. We don't want it to turn some random function by the name of `@free` into the actual `@free` function and suddenly change how LLVM handles it. > > So what do we do? > > One option is to make `argpromotion` and every other pass that mutates a function's signature rename the function (or add a `nobuiltin` attribute to it). However, this seems brittle and somewhat complicated. > > My proposal is that we admit that certain names of functions are reserved in LLVM's IR. For these names, in some cases *any* function with that name will be treated specially by the optimizer. We can still check the signatures when transforming code based on LLVM's semantic understanding of that function, but this avoids any need to check things when mutating the signature of the function. > > This would require frontends to avoid emitting functions by these names unless they should have these special semantics. However, even if they do, everything should remain conservatively correct. But I'll send an email to cfe-dev suggesting that Clang start "mangling" internal functions that collide with target names. I think this is important as I've found a quite surprising number of cases where this happens in real code. > > There is no need to auto-upgrade here, because again, LLVM's handling will remain conservatively correct. > > Does this seem reasonable? If so, I'll send patches to update the LangRef with these restrictions. I'll also take a quick stab at generating some example tables of such names from the .td files used by `TargetLibraryInfo` already. These can't be authoritative because of the platform-specific nature of it, but should help people understand how this area works. > > > One alternative that seems appealing but doesn't actually help would be to make `TargetLibraryInfo` ignore internal functions. That is how the C++ spec seems to handle this for example (C library function names are reserved only when they have linkage). But this doesn't work well for LLVM because we want to be able to LTO an internalized C library. So I think we need the rule for LLVM function names to not rely on linkage here. > > > Thanks, > -Chandler > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev_______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/c110639b/attachment-0001.html>
David Majnemer via llvm-dev
2017-Oct-27 18:27 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
In general, I think we are better off phrasing attributes as giving optimization power rather than restricting it. It allows for a naive optimization pass to avoid considering attributes at all. On Fri, Oct 27, 2017 at 11:15 AM, Robinson, Paul via llvm-dev < llvm-dev at lists.llvm.org> wrote:> +1 to what the Davids said. This could also help address the situation > that the Android keynote mentioned at last week's dev meeting: if you're > building the implementation of the library you don't want the compiler to > wave its magic wand because it knows better than you. > > --paulr > > > > *From:* llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] *On Behalf Of *Xinliang > David Li via llvm-dev > *Sent:* Friday, October 27, 2017 11:11 AM > *To:* David Chisnall > *Cc:* llvm-dev > *Subject:* Re: [llvm-dev] RFC: We need to explicitly state that some > functions are reserved by LLVM > > > > > > > > On Fri, Oct 27, 2017 at 1:50 AM, David Chisnall via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > This seems slightly inverted. As I understand it, the root of the problem > is that some standards, such as C, C++, and POSIX, define some functions as > special and we rely on their specialness when optimising. Unfortunately, > the specialness is a property of the source language and, possibly, > environment and not necessarily of the target. The knowledge of which > functions are special seems like it ought to belong in the front end, so a > C++ compiler might tag a function called _Znwm as special, but to a C or > Fortran front end this is just another function and shouldn’t be treated > specially. > > Would it not be cleaner to have the front end (and any optimisations that > are aware of special behaviour of functions) add metadata indicating that > these functions are special? > > > > > > Ideally many of these functions should be annotated as builtin in the > system headers. An hacky solution is for frontend to check if the > declarations are from system headers to decide if metadata needs to be > applied. > > > > David > > > > > > If the metadata is lost, then this inhibits later optimisations but > shouldn’t affect the semantics of the code (it’s always valid to treat the > special functions as non-special functions) and optimisations then don’t > need to mark them. This would also give us a free mechanism of specifying > functions that are semantically equivalent but have different spellings. > > > > > > > > David > > > > On 27 Oct 2017, at 04:14, Chandler Carruth via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > I've gotten a fantastic bug report. Consider the LLVM IR: > > > > target triple = "x86_64-unknown-linux-gnu" > > > > define internal i8* @access({ i8* }* %arg, i64) { > > ret i8* undef > > } > > > > define i8* @g({ i8* }* %arg) { > > bb: > > %tmp = alloca { i8* }*, align 8 > > store { i8* }* %arg, { i8* }** %tmp, align 8 > > br i1 undef, label %bb4, label %bb1 > > > > bb1: > > %tmp2 = load { i8* }*, { i8* }** %tmp, align 8 > > %tmp3 = call i8* @access({ i8* }* %tmp2, i64 undef) > > br label %bb4 > > > > bb4: > > ret i8* undef > > } > > > > This IR, if compiled with `opt -passes='cgscc(inline,argpromotion)' > -disable-output` hits a bunch of asserts in the LazyCallGraph. > > > > The problem here is that `argpromotion` turns a normal looking function > `i8* @access({ i8* }* %arg, i64)` and turn it into a magical function `i8* > @access(i8* %arg, i64)`. This latter signature is the POSIX `access` > function that LLVM's `TargetLibraryInfo` knows magical things about. > > > > Because *some* library functions known to `TargetLibraryInfo` can have > *calls* to them introduced at arbitrary points of optimization (consider > vectorized variants of math functions), the new pass manager and its graph > to provide ordering over the module get Very Unhappy when you *introduce* a > definition of a library function in the middle of the compilation pipeline. > > > > And really, we do *not* want `argpromotion` to do this. We don't want it > to turn some random function by the name of `@free` into the actual `@free` > function and suddenly change how LLVM handles it. > > > > So what do we do? > > > > One option is to make `argpromotion` and every other pass that mutates a > function's signature rename the function (or add a `nobuiltin` attribute to > it). However, this seems brittle and somewhat complicated. > > > > My proposal is that we admit that certain names of functions are > reserved in LLVM's IR. For these names, in some cases *any* function with > that name will be treated specially by the optimizer. We can still check > the signatures when transforming code based on LLVM's semantic > understanding of that function, but this avoids any need to check things > when mutating the signature of the function. > > > > This would require frontends to avoid emitting functions by these names > unless they should have these special semantics. However, even if they do, > everything should remain conservatively correct. But I'll send an email to > cfe-dev suggesting that Clang start "mangling" internal functions that > collide with target names. I think this is important as I've found a quite > surprising number of cases where this happens in real code. > > > > There is no need to auto-upgrade here, because again, LLVM's handling > will remain conservatively correct. > > > > Does this seem reasonable? If so, I'll send patches to update the > LangRef with these restrictions. I'll also take a quick stab at generating > some example tables of such names from the .td files used by > `TargetLibraryInfo` already. These can't be authoritative because of the > platform-specific nature of it, but should help people understand how this > area works. > > > > > > One alternative that seems appealing but doesn't actually help would be > to make `TargetLibraryInfo` ignore internal functions. That is how the C++ > spec seems to handle this for example (C library function names are > reserved only when they have linkage). But this doesn't work well for LLVM > because we want to be able to LTO an internalized C library. So I think we > need the rule for LLVM function names to not rely on linkage here. > > > > > > Thanks, > > -Chandler > > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/57112e68/attachment.html>
Hal Finkel via llvm-dev
2017-Oct-27 18:31 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
On 10/27/2017 01:10 PM, Xinliang David Li via llvm-dev wrote:> > > On Fri, Oct 27, 2017 at 1:50 AM, David Chisnall via llvm-dev > <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > > This seems slightly inverted. As I understand it, the root of the > problem is that some standards, such as C, C++, and POSIX, define > some functions as special and we rely on their specialness when > optimising. Unfortunately, the specialness is a property of the > source language and, possibly, environment and not necessarily of > the target. The knowledge of which functions are special seems > like it ought to belong in the front end, so a C++ compiler might > tag a function called _Znwm as special, but to a C or Fortran > front end this is just another function and shouldn’t be treated > specially. > > Would it not be cleaner to have the front end (and any > optimisations that are aware of special behaviour of functions) > add metadata indicating that these functions are special? > > > > Ideally many of these functions should be annotated as builtin in the > system headers. An hacky solution is for frontend to check if the > declarations are from system headers to decide if metadata needs to be > applied.I agree. Marking external functions from system headers seems like a reasonable heuristic. We'd need some heuristic because it's not reasonable for the frontend to know about every function the optimizer knows about. Over-marking seems okay, however. -Hal> > David > > If the metadata is lost, then this inhibits later optimisations > but shouldn’t affect the semantics of the code (it’s always valid > to treat the special functions as non-special functions) and > optimisations then don’t need to mark them. This would also give > us a free mechanism of specifying functions that are semantically > equivalent but have different spellings. > > > > David > > > On 27 Oct 2017, at 04:14, Chandler Carruth via llvm-dev > <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > > > > I've gotten a fantastic bug report. Consider the LLVM IR: > > > > target triple = "x86_64-unknown-linux-gnu" > > > > define internal i8* @access({ i8* }* %arg, i64) { > > ret i8* undef > > } > > > > define i8* @g({ i8* }* %arg) { > > bb: > > %tmp = alloca { i8* }*, align 8 > > store { i8* }* %arg, { i8* }** %tmp, align 8 > > br i1 undef, label %bb4, label %bb1 > > > > bb1: > > %tmp2 = load { i8* }*, { i8* }** %tmp, align 8 > > %tmp3 = call i8* @access({ i8* }* %tmp2, i64 undef) > > br label %bb4 > > > > bb4: > > ret i8* undef > > } > > > > This IR, if compiled with `opt > -passes='cgscc(inline,argpromotion)' -disable-output` hits a bunch > of asserts in the LazyCallGraph. > > > > The problem here is that `argpromotion` turns a normal looking > function `i8* @access({ i8* }* %arg, i64)` and turn it into a > magical function `i8* @access(i8* %arg, i64)`. This latter > signature is the POSIX `access` function that LLVM's > `TargetLibraryInfo` knows magical things about. > > > > Because *some* library functions known to `TargetLibraryInfo` > can have *calls* to them introduced at arbitrary points of > optimization (consider vectorized variants of math functions), the > new pass manager and its graph to provide ordering over the module > get Very Unhappy when you *introduce* a definition of a library > function in the middle of the compilation pipeline. > > > > And really, we do *not* want `argpromotion` to do this. We don't > want it to turn some random function by the name of `@free` into > the actual `@free` function and suddenly change how LLVM handles it. > > > > So what do we do? > > > > One option is to make `argpromotion` and every other pass that > mutates a function's signature rename the function (or add a > `nobuiltin` attribute to it). However, this seems brittle and > somewhat complicated. > > > > My proposal is that we admit that certain names of functions are > reserved in LLVM's IR. For these names, in some cases *any* > function with that name will be treated specially by the > optimizer. We can still check the signatures when transforming > code based on LLVM's semantic understanding of that function, but > this avoids any need to check things when mutating the signature > of the function. > > > > This would require frontends to avoid emitting functions by > these names unless they should have these special semantics. > However, even if they do, everything should remain conservatively > correct. But I'll send an email to cfe-dev suggesting that Clang > start "mangling" internal functions that collide with target > names. I think this is important as I've found a quite surprising > number of cases where this happens in real code. > > > > There is no need to auto-upgrade here, because again, LLVM's > handling will remain conservatively correct. > > > > Does this seem reasonable? If so, I'll send patches to update > the LangRef with these restrictions. I'll also take a quick stab > at generating some example tables of such names from the .td files > used by `TargetLibraryInfo` already. These can't be authoritative > because of the platform-specific nature of it, but should help > people understand how this area works. > > > > > > One alternative that seems appealing but doesn't actually help > would be to make `TargetLibraryInfo` ignore internal functions. > That is how the C++ spec seems to handle this for example (C > library function names are reserved only when they have linkage). > But this doesn't work well for LLVM because we want to be able to > LTO an internalized C library. So I think we need the rule for > LLVM function names to not rely on linkage here. > > > > > > Thanks, > > -Chandler > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/051f6b09/attachment.html>
Michael Kruse via llvm-dev
2017-Oct-28 00:51 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
2017-10-27 20:31 GMT+02:00 Hal Finkel via llvm-dev <llvm-dev at lists.llvm.org>:> I agree. Marking external functions from system headers seems like a > reasonable heuristic. We'd need some heuristic because it's not reasonable > for the frontend to know about every function the optimizer knows about. > Over-marking seems okay, however.Sorry for the naive question, why is it unreasonable for the frontend to know about special functions? It is the frontend who defines a source language function's semantics. Clang also has access (or can be made to can get access) to TargetLibraryInfo, no? The most straightforward solution seems to have an intrinsic for every function that has compiler magic, meaning every other function is ordinary without worrying about hitting a special case (e.g. when concatenating strings to create new function names when outlining). Recognizing functions names and assuming they represent the semantics from libs seems "unclean", tying LLVM IR more closely to C and a specific platform's libc/libm than necessary. "malloc" once had an intrinsic. Why was it removed, and recognized by name instead? Michael
Alex Bradbury via llvm-dev
2017-Nov-04 20:58 UTC
[llvm-dev] RFC: We need to explicitly state that some functions are reserved by LLVM
On 27 October 2017 at 19:31, Hal Finkel via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I agree. Marking external functions from system headers seems like a > reasonable heuristic. We'd need some heuristic because it's not reasonable > for the frontend to know about every function the optimizer knows about. > Over-marking seems okay, however.I think this is the pragmatic way forwards. For a concise example of how broken/surprising the current behaviour is: This IR: """ define double @floor(double %a) nounwind readnone { call void @abort() unreachable } define double @foo(float %a) nounwind { %1 = fpext float %a to double %2 = call double @floor(double %1) ret double %2 } declare void @abort() """ Results in the following SelectionDAG: """ Initial selection DAG: BB#0 'foo:' SelectionDAG has 8 nodes: t0: ch = EntryToken t2: f32,ch = CopyFromReg t0, Register:f32 %vreg0 t3: f64 = fp_extend t2 t4: f64 = ffloor t3 t6: ch,glue = CopyToReg t0, Register:f64 %D0, t4 t7: ch = AArch64ISD::RET_FLAG t6, Register:f64 %D0, t6:1 """ And the following machine code: """ .globl foo // -- Begin function foo .p2align 2 .type foo, at function foo: // @foo // BB#0: fcvt d0, s0 frintm d0, d0 ret .Lfunc_end1: .size foo, .Lfunc_end1-foo // -- End function """ ffloor is legal for AArch64, meaning frintm is produced rather than a call to floor. Deleting the 'readnone' attribute from the floor function will avoid lowering to ffloor. Compile with -mtriple=arm and the generated assembly has completely different semantics (calling floor and so aborting). I'm not sure if there's a tracking bug for this, but the earliest mention I could find with a quick search was <https://bugs.llvm.org/show_bug.cgi?id=2141>. Best, Alex