First Last Prev Next    No search results available
Details
: Icky code generated for std::min/std::max
Bug#: 362
: libraries
: Scalar Optimizations
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: enhancement
: 1.4

:
: code-quality
:
:
  Show dependency tree - Show dependency graph
People
Reporter: Chris Lattner <sabre@nondot.org>
Assigned To: Chris Lattner <sabre@nondot.org>

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2004-06-07 19:11
Consider this C++ testcase:

--------
#include <algorithm>
void test1(int &x, int &y) {
    x = std::min(x,y);
}

void test2(int &x, int &y) {
    int tmp = x;
    y = std::max(tmp,y);
}
--------

We're currently compiling this into:

void %_Z5test1RiS_(int* %x, int* %y) {
entry:
        %tmp.1.i = load int* %y
        %tmp.3.i = load int* %x
        %tmp.4.i = setlt int %tmp.1.i, %tmp.3.i
        %retval.i = select bool %tmp.4.i, int* %y, int* %x
        %tmp.4 = load int* %retval.i
        store int %tmp.4, int* %x
        ret void
}

Note that for this function the %tmp.4 load is redundant with the loads of X or
Y. It would be better to select one of those load's values.


void %_Z5test2RiS_(int* %x, int* %y) {
entry:
        %tmp.0 = alloca int
        %tmp.2 = load int* %x
        store int %tmp.2, int* %tmp.0
        %tmp.3.i = load int* %y
        %tmp.4.i = setlt int %tmp.2, %tmp.3.i
        %retval.i = select bool %tmp.4.i, int* %y, int* %tmp.0
        %tmp.6 = load int* %retval.i
        store int %tmp.6, int* %y
        ret void
}

This is even worse.  Here we are doing the same thing, selecting the address of
Y or the tmp.  Because we need it's address, we are not able to register promote
the tmp, leaving it as an alloca.  :(

We should transform these selects into selects of the value not of the pointer
when safe.

-Chris
------- Comment #1 From Chris Lattner 2004-06-20 03:43:47 -------
Note that the trick to this bug is the whole "when safe" bit.  In particular, we
can only turn "*(cond ? P1 : P2)" into "(cond ? *P1 : *P2)" when we know it's
safe to dereference P1 and P2.

-Chris
------- Comment #2 From Chris Lattner 2004-09-19 14:19:08 -------
Implemented.

Patch here:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040913/018402.html

Testcase here:
test/Regression/Transforms/InstCombine/CPP_min_max.llx

-Chris

First Last Prev Next    No search results available