(original) (raw)
Hi Roman,
Thanks for your good idea. I think it can solve the abs issue very well. I can continue with my work now^-^.
But if it is not abs and there is no select,
%res = OP i32 %b, %a
%sub = sub i32 0, %b
%res2 = OP i32 %sub, %a
theoretically, we can still do the following transform for the above pattern:
%res2 = OP i32 %sub, %a ==> %res2 = sub i32 0, %res
Not sure whether we can do it in instCombine.
Thanks.
BRS//
Chen Zheng
Power Compiler Backend DeveloperRoman Lebedev ---2018/12/18 03:45:06 PM---On Tue, Dec 18, 2018 at 10:18 AM Zheng CZ Chen via llvm-dev wrote:
From: Roman Lebedev
To: Zheng CZ Chen
Cc: llvm-dev@lists.llvm.org
Date: 2018/12/18 03:45 PM
Subject: Re: \[llvm-dev\] should we do this time-consuming transform in InstCombine?
On Tue, Dec 18, 2018 at 10:18 AM Zheng CZ Chen via llvm-dev
wrote:
>
> Hi,
Hi.
> There is an opportunity in instCombine for following instruction pattern:
>
> %mul = mul nsw i32 %b, %a
> %cmp = icmp sgt i32 %mul, -1
> %sub = sub i32 0, %a
> %mul2 = mul nsw i32 %sub, %b
> %cond = select i1 %cmp, i32 %mul, i32 %mul2
>
> Source code for above pattern:
> return (a\*b) >=0 ? (a\*b) : -a\*b;
>
> Currently, llvm(-O3) can not recognize this as abs(a\*b).
>
> I initially think we could do this in instCombine phase in opt. Below is what I think:
>
> %res = OP i32 %b, %a
> %sub = sub i32 0, %b
> %res2 = OP i32 %sub, %a
>
> We could do the transform:
> %res2 = OP i32 %sub, %a ==> %res2 = sub i32 0, %res
>
> Then we can get the advantage:
> 1: if %res2 is the only user of %sub, %sub can be eliminated;
> 2: if %res2 is not the only user of %sub, we could change some heavy instruction like div to sub;
> 3: expose more abs opportunity for later pass.
>
> But my concern is finding %res is a little compiling time-consuming.
> At least we need MIN(user\_count(%b), user\_count(%a)) times to check if instruction with same opcode and same operands exists.
In instcombine, no user checking is performed/allowed.
This should match that \*specific\* pattern (other than verifying the
correct equal binop types), although i have not tested it:
ICmpInst::Predicate Pred;
Value \*A, \*B, \*Mul, \*Sub, \*Mul2;
if (match(&SI,
m\_Select(m\_ICmp(Pred,
m\_CombineAnd(m\_BinOp(m\_Value(A), m\_Value(B)),
m\_Value(Mul)),
m\_AllOnes()),
m\_Deferred(Mul),
m\_CombineAnd(
m\_c\_BinOp(m\_CombineAnd(m\_Sub(m\_Zero(), m\_Deferred(A)),
m\_Value(Sub)),
m\_Deferred(B)),
m\_Value(Mul2)))) &&
Pred == ICmpInst::Predicate::ICMP\_SGT) {
}
> Could you guys give some comment? Is there any better idea for this transform?
>
> Thanks.
>
> BRS//
> Chen Zheng
> Power Compiler Backend Developer
Roman.
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
> LLVM Developers mailing list
> llvm-dev@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev