[llvm-dev] Why is llvm.maxnum.f32 coming through unreduced?

47 views
Skip to first unread message

Rodney M. Bates via llvm-dev

unread,
Nov 15, 2015, 12:02:16 PM11/15/15
to llvm...@lists.llvm.org
I have a smallish compilation that contains calls on intrinsics
@llvm.maxnum.f32 and @llvm.fabs.f32:

%fminmax = call float @llvm.maxnum.f32(float %fabs5, float %fabs)
%fabs = call float @llvm.fabs.f32(float %v.6)

The latter is reduced to machine code by llc, the former is not, instead
coming through as an external function call, which then fails to link.


I can't see any differences that look significant to me. Both have declarations:

; Function Attrs: nounwind readnone
declare float @llvm.maxnum.f32(float, float) #2
; Function Attrs: nounwind readonly
declare float @llvm.fabs.f32(float) #1

These are both created in my front end by effectively calling (after
removing some levels of bindings, wrappings, etc.)

Intrinsic::getDeclaration( M, Intrinsic::maxnum, Tys)
Intrinsic::getDeclaration( M, Intrinsic::fabs, Tys)

where Tys contains a single floating type.

As generated, both declarations occur after the calls, but moving the
maxnum decl before the calls changes nothing.

This is llvm 3.6.1.

Any help would be appreciated.

--
Rodney Bates
rodney....@acm.org
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Tim Northover via llvm-dev

unread,
Nov 15, 2015, 2:29:56 PM11/15/15
to rodney....@acm.org, Rodney M. Bates, LLVM Developers Mailing List
On 15 November 2015 at 09:01, Rodney M. Bates via llvm-dev

<llvm...@lists.llvm.org> wrote:
> The latter is reduced to machine code by llc, the former is not, instead
> coming through as an external function call, which then fails to link.

Is this for x86? I don't think that has a single instruction to
implement floating-point maximum so I'd expect LLVM to produce a call
to fmax. Sanjay seems to have proposed an efficient inlined version
(https://llvm.org/bugs/show_bug.cgi?id=24475), but given that the
bug's still open it probably hasn't actually been implemented.

To get the libcall working (depending on the platform), you might need
to link against libm.

Cheers.

Tim.

Sanjay Patel via llvm-dev

unread,
Nov 15, 2015, 6:52:03 PM11/15/15
to Tim Northover, LLVM Developers Mailing List, Rodney M. Bates
Yep - I filed the bug, but I didn't get back around to creating a patch.
As noted in the bug report: in the case where both inputs are NaN, we'd always return the 2nd NaN value. That wouldn't match the existing OSX x86 libm implementation that I checked, but that's ok?
For Apple folks, I filed rdar://22308033 for the libm implementation.

Rodney M. Bates via llvm-dev

unread,
Nov 16, 2015, 12:45:55 PM11/16/15
to Tim Northover, LLVM Developers Mailing List

On 11/15/2015 01:29 PM, Tim Northover wrote:
> On 15 November 2015 at 09:01, Rodney M. Bates via llvm-dev
> <llvm...@lists.llvm.org> wrote:
>> The latter is reduced to machine code by llc, the former is not, instead
>> coming through as an external function call, which then fails to link.
>
> Is this for x86? I don't think that has a single instruction to
> implement floating-point maximum so I'd expect LLVM to produce a call
> to fmax. Sanjay seems to have proposed an efficient inlined version
> (https://llvm.org/bugs/show_bug.cgi?id=24475), but given that the
> bug's still open it probably hasn't actually been implemented.

Yes, it's x86_64. That makes sense, but I can't find the needed library,
which was what I first tried. I already have -lm in my link command, and
nm on my libm doesn't get it.

With a link name like "llvm.maxnum.f32", I would expect it to be provided
by the llvm distribution. But I find no occurrence in either my installed
lib directory nor my build directory, using nm and grep. The closest I can
find is a mangled name with only "maxnum" as a substring. In my source
directory, it occurs only in llvm assembly code, with a "@" prefix, in
subdirectories doc and test.

Am I be missing part of llvm? I do have compiler-rt.

>
> To get the libcall working (depending on the platform), you might need
> to link against libm.
>
> Cheers.
>
> Tim.
>

--
Rodney Bates
rodney....@acm.org

Tim Northover via llvm-dev

unread,
Nov 16, 2015, 12:54:34 PM11/16/15
to rodney....@acm.org, LLVM Developers Mailing List
On 16 November 2015 at 09:45, Rodney M. Bates <rodney...@lcwb.coop> wrote:
> With a link name like "llvm.maxnum.f32", I would expect it to be provided
> by the llvm distribution.

Ah, it ought to have been converted into an "fmaxf" call. It's
possible that's a bug in LLVM 3.6 and the intrinsic wasn't supported
on x86 then, since it works for me on trunk:

$ cat simple.ll
define float @foo(float %l, float %r) {
%res = call float @llvm.maxnum.f32(float %l, float %r)
ret float %res
}
declare float @llvm.maxnum.f32(float, float)
$ bin/llc -mtriple=x86_64-apple-darwin simple.ll -o -
[...]
foo: # @foo
.cfi_startproc
# BB#0:
jmp fmaxf # TAILCALL
.cfi_endproc

Alternatively (if that works for you too), it might be some kind of
misconfiguration in your front-end, though that seems a bit unlikely.

Tim.

Rodney M. Bates via llvm-dev

unread,
Nov 16, 2015, 9:32:58 PM11/16/15
to Tim Northover, LLVM Developers Mailing List

On 11/16/2015 11:54 AM, Tim Northover wrote:
> On 16 November 2015 at 09:45, Rodney M. Bates <rodney...@lcwb.coop> wrote:
>> With a link name like "llvm.maxnum.f32", I would expect it to be provided
>> by the llvm distribution.
>
> Ah, it ought to have been converted into an "fmaxf" call. It's
> possible that's a bug in LLVM 3.6 and the intrinsic wasn't supported
> on x86 then, since it works for me on trunk:
>
> $ cat simple.ll
> define float @foo(float %l, float %r) {
> %res = call float @llvm.maxnum.f32(float %l, float %r)
> ret float %res
> }
> declare float @llvm.maxnum.f32(float, float)
> $ bin/llc -mtriple=x86_64-apple-darwin simple.ll -o -
> [...]
> foo: # @foo
> .cfi_startproc
> # BB#0:
> jmp fmaxf # TAILCALL
> .cfi_endproc
>
> Alternatively (if that works for you too), it might be some kind of
> misconfiguration in your front-end, though that seems a bit unlikely.
>

Thanks, this got me going. Actually, it was an installation error.
llc 3.6.1 handles it correctly, but an old llc 3.4.2 was getting picked
up instead, and it does not.

> Tim.
>

--
Rodney Bates
rodney....@acm.org

Reply all
Reply to author
Forward
0 new messages