Reassociation will remove nsw/nuw flags after change the order of computation. It may block IndVar from doing IV use widening and also block the optimization of LSR.
For %sub1 = %i.0 + %size - 1 in the following testcase, reassociation will convert it to %sub1 = %size - 1 + %i.0 and remove all the nsw flags. Then IndVar cannot do widening for %idxprom and cannot remove the sext. In addition, LSR cannot regard %arrayidx as an induction variable and it may produce suboptimal result.
for.body:
%add = add nsw i32 %i.0, %size %sub1 = add nsw i32 %add, -1 %idxprom = sext i32 %sub1 to i64 %arrayidx = getelementptr inbounds [1000 x i32], [1000 x i32]* @maxarray, i64 0, i64 %idxprom %tmp0 = load i32, i32* %arrayidx, align 4 %tmp1 = load i32, i32* @total, align 4 %add2 = add nsw i32 %tmp1, %tmp0 store i32 %add2, i32* @total, align 4 %inc = add nsw i32 %i.0, 1 br label %for.cond
The patch skips reassociation for IV use when it contains NSW/NUW flags so as to let IndVar and LSR do better jobs. Because LSR will also do reassociation work in its Formula canonicalization, we won't lose performance opportunity mostly.