[llvm] [InstCombine] Fold more 'fcmp' 'select' instrs idioms into 'fabs' (PR #83381)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 02:21:37 PDT 2024


sushgokh wrote:

There are some additional issues with having attributes on function args(although it may help for this particular case).

Having attributes on the function arguments does not come into picture for the following scenarios:
1. Global variable
```
double x;
double foo()
{
  if(x < 0.0)
    return -x;
  else
    return x;
}
```
2. local variable
```
double foo()
{
   double x;
   scanf(x);
   if (x < 0.0)
        return -x;
    else
        return x;
}
```

Moreover, there is fundamental problem with the IR generated for the motivating example.
```
define double @foo(double %x)
{
entry:
  %cmp = fcmp fast olt double %x, 0.000000e+00     ----------- (1)
  %fneg = fneg fast double %x                      ----------- (2)
  %retval.0 = select i1 %cmp, double %fneg, double %x
  ret double %retval.0
}
```
While nsz flag have been used to enable certain class of optimisations, its presence above in (1) and (2) is actually disabling fabs() optimisation i.e. the meaning of the program is lost with presence of nsz flag. Without nsz flag, as shown below, the meaning is crystal clear and it can easily be turned into fabs() 
```
define double @foo_without_nsz(double %x)
{
entry:
  %cmp = fcmp  olt double %x, 0.000000e+00     
  %fneg = fneg  double %x                      
  %retval.0 = select i1 %cmp, double %fneg, double %x
  ret double %retval.0
}
```
So, one of the things we can consider is removing nsz flag on the  operations that are inherently sensitive to sign of the operand i.e. fcmp, fneg etc.


https://github.com/llvm/llvm-project/pull/83381


More information about the llvm-commits mailing list