Why is llvm.maxnum.f32 coming through unreduced?

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.

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.

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.

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.

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.

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.