[InstCombine] Missed optimization for pow(x, y) * pow(x, z) with fast-math
authorDaniil Seredkin <vdsered@gmail.com>
Mon, 7 Jun 2021 11:01:29 +0000 (07:01 -0400)
committerSanjay Patel <spatel@rotateright.com>
Mon, 7 Jun 2021 12:08:05 +0000 (08:08 -0400)
commit7736c1936a93d7effecf32ef5193dfc00b732cd2
tree4ac5e80435c8637e9aee3d2d6eb9e8ebf9d3b84b
parent2def12ebc6cc904cddb4bc608df63014ec2bfe86
[InstCombine] Missed optimization for pow(x, y) * pow(x, z) with fast-math

If FP reassociation (fast-math) is allowed, then LLVM is free to do the
following transformation pow(x, y) * pow(x, z) -> pow(x, y + z).
This patch adds this transformation and tests for it.
See more https://bugs.llvm.org/show_bug.cgi?id=47205

It handles two cases

1. When operands of fmul are different instructions

%4 = call reassoc float @llvm.pow.f32(float %0, float %1)
%5 = call reassoc float @llvm.pow.f32(float %0, float %2)
%6 = fmul reassoc float %5, %4
-->
%3 = fadd reassoc float %1, %2
%4 = call reassoc float @llvm.pow.f32(float %0, float %3)

2. When operands of fmul are the same instruction

%4 = call reassoc float @llvm.pow.f32(float %0, float %1)
%5 = fmul reassoc float %4, %4
-->
%3 = fadd reassoc float %1, %1
%4 = call reassoc float @llvm.pow.f32(float %0, float %3)

Differential Revision: https://reviews.llvm.org/D102574
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/fmul-pow.ll