[LLVMdev] Min and max
Chris Lattner
sabre at nondot.org
Tue May 27 20:54:44 PDT 2008
On May 27, 2008, at 2:49 AM, Nicolas Capens wrote:
> Hi all,
>
> I’m trying to implement a floating-point ‘min’ and ‘max’ operation
> using select. For ‘min’ I get the expected x86 assembly minss
> instruction, but for ‘max’ I get a branch instead of maxss.
>
> The corresponding C syntax code looks like this:
>
> float z = (x > y) ? x : y;
>
> Any clues?
Your code is not safe for NaNs. This is the correct way to write
maxss in C:
float max(float x, float y) {
return !(x < y) ? x : y;
}
If you don't care about NaNs, you can pass -ffast-math to llvm-gcc, or
set "UnsafeFPMath=true" from <llvm/Target/TargetOptions.h>
> Could someone maybe explain to me the basics of LLVM’s target
> specific optimizations and code generation? I’d love to analyze
> things like this myself but I don’t know where to start.
This one specifically boils down to the semantics of maxss and LLVM IR
instructions. For example, this code:
float not_max(float x, float y) {
return (x > y) ? x : y;
}
float really_max(float x, float y) {
return !(x < y) ? x : y;
}
compiles into this LLVM IR (llvm-gcc t.c -S -o - -O -emit-llvm):
define float @not_max(float %x, float %y) nounwind {
entry:
%tmp3 = fcmp ogt float %x, %y ; <i1> [#uses=1]
%iftmp.0.0 = select i1 %tmp3, float %x, float %y ; <float> [#uses=1]
ret float %iftmp.0.0
}
define float @really_max(float %x, float %y) nounwind {
entry:
%tmp3 = fcmp uge float %x, %y ; <i1> [#uses=1]
%iftmp.1.0 = select i1 %tmp3, float %x, float %y ; <float> [#uses=1]
ret float %iftmp.1.0
}
If you're interested in target-specific x86 optimizations to be done,
take a look at lib/Target/X86/README*.txt
-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080527/e36b59e5/attachment.html>
More information about the llvm-dev
mailing list