Nema, Ashutosh
2015-Apr-15 08:52 UTC
[LLVMdev] Instruction combiner multiplication canonicalization
Hi,
I observed below behavior with Instruction combiner (visitMul Canonicalization)
It tries to convert "(X+C1)*C2" to "X*C2+C1*C2"
While transforming if operation is guaranteed to not overflow it does not
reflect same property to transformed instructions.
Consider following scenarios:
1) If input is ((X+C1)*C2)<nsw>
Then post canonicalization output should be (X*C2+C1*C2) <nsw>
2) If input is (((X+C1)<nsw>)*C2)<nsw>
Then post canonicalization output should be ((X*C2) <nsw>+(C1*C2)
<nsw>) <nsw>
** C1 & C2 are constants.
Current canonicalization transforms to (X*C2+C1*C2) in both scenarios (1 &
2).
To me this looks like a limitation with canonicalization where its missing
guarantee to not overflow property.
Please confirm my understanding.
<File: InstCombineMulDivRem.cpp >
168 Instruction *InstCombiner::visitMul(BinaryOperator &I) {
268 // Canonicalize (X+C1)*CI -> X*CI+C1*CI.
269 {
270 Value *X;
271 Constant *C1;
272 if (match(Op0, m_OneUse(m_Add(m_Value(X), m_Constant(C1))))) {
273 Value *Mul = Builder->CreateMul(C1, Op1);
274 // Only go forward with the transform if C1*CI simplifies to a
tidier
275 // constant.
276 if (!match(Mul, m_Mul(m_Value(), m_Value())))
277 return BinaryOperator::CreateAdd(Builder->CreateMul(X, Op1),
Mul);
278 }
279 }
If my understanding is correct then I like propose below change here:
If input operation to canonicalization is guaranteed to not overflow then
transformed operation should have the same property.
Specifically I like to handle above explained 2 scenarios for 'nsw'
& 'nuw'.
Regards,
Ashutosh
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150415/03bae597/attachment.html>
Sanjoy Das
2015-Apr-15 17:13 UTC
[LLVMdev] Instruction combiner multiplication canonicalization
> Consider following scenarios: > 1) If input is ((X+C1)*C2)<nsw> > Then post canonicalization output should be (X*C2+C1*C2) <nsw>Say X = INT_SMAX, C1 = C2 = 1. Then (X + C1) = INT_SMIN and INT_SMIN * 1 does not overflow. But X*C2 = INT_SMAX and C1*C2 = 1 and INT_SMAX + 1 does sign overflow.> 2) If input is (((X+C1)<nsw>)*C2)<nsw> > Then post canonicalization output should be ((X*C2) <nsw>+(C1*C2) <nsw>) > <nsw>This is more interesting, let X = INT_SMIN, C1 = 1, C2 -1. Then the first set of operations don't sign overflow. But X * C2 INT_SMIN * -1 will sign overflow -- Sanjoy
Nema, Ashutosh
2015-Apr-16 11:40 UTC
[LLVMdev] Instruction combiner multiplication canonicalization
Thanks Sanjoy for detailed explanation. I got your point, there is a possibility of overflow. Hence we can't do explained transformation. Regards, Ashutosh -----Original Message----- From: Sanjoy Das [mailto:sanjoy at playingwithpointers.com] Sent: Wednesday, April 15, 2015 10:43 PM To: Nema, Ashutosh Cc: llvmdev at cs.uiuc.edu; Nick Lewycky Subject: Re: Instruction combiner multiplication canonicalization> Consider following scenarios: > 1) If input is ((X+C1)*C2)<nsw> > Then post canonicalization output should be (X*C2+C1*C2) <nsw>Say X = INT_SMAX, C1 = C2 = 1. Then (X + C1) = INT_SMIN and INT_SMIN * 1 does not overflow. But X*C2 = INT_SMAX and C1*C2 = 1 and INT_SMAX + 1 does sign overflow.> 2) If input is (((X+C1)<nsw>)*C2)<nsw> > Then post canonicalization output should be ((X*C2) <nsw>+(C1*C2) <nsw>) > <nsw>This is more interesting, let X = INT_SMIN, C1 = 1, C2 -1. Then the first set of operations don't sign overflow. But X * C2 INT_SMIN * -1 will sign overflow -- Sanjoy
Seemingly Similar Threads
- [LLVMdev] Probable error in InstCombine
- [LLVMdev] More info, was Help needed after hiatus
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??