[PATCH] Fixing inst-combine not to drops nsw when combining adds into mul (PR19263)

Dinesh Dwivedi dinesh.d at samsung.com
Tue Jun 17 13:50:00 PDT 2014


typo :(

================
Comment at: lib/Transforms/InstCombine/InstructionCombining.cpp:466
@@ +465,3 @@
+      bool InnerCommutative = Instruction::isCommutative(LHSOpcode);
+      // Does "X op' (Y op Z)" always equal "(X op' Y) op (X op' Z)"?
+      if (LeftDistributesOverRight(LHSOpcode, TopLevelOpcode))
----------------
Dinesh Dwivedi wrote:
> Jingyue Wu wrote:
> > Dinesh Dwivedi wrote:
> > > Jingyue Wu wrote:
> > > > I feel the logic of this IF and next IF (if (RightDistributesOverLeft) a bit difficult to follow. There is also some copy and paste. What about extracting the check on InnerCommutative out? Something like:
> > > > ```
> > > > try(a, b, c, d);
> > > > if (op' is commutative) {
> > > >   try(b, a, c, d);
> > > >   try(a, b, d, c);
> > > >   try(b, a, c, d);
> > > > }
> > > > ```
> > > > By doing this, inside each "try", we don't need to think about whether op' is commutative. 
> > > > 
> > > > What do you think?
> > > Updated patch to handle this. We can not just depend on isCommutative as
> > > there are oparation which are not commutative but still can be distributed e.g.
> > > "(X + Y) / Z = X/Z + Y/Z"
> > > 
> > > We do not handle this now but we might want to do it in future.
> > I think the first "try" in my pseudo-code handle this case. Right? 
> > 
> > While "try" doesn't swap a and b or c and d, it considers both LeftDistributesOverRight and RightDistributesOverLeft. Therefore, it is able to convert "a / b + c / d" to "(a + c) / d". 
> Yes, if we considers both LeftDistributesOverRight and RightDistributesOverLeft, it handles all cases. 
> But then I think current code is handling all cases more efficiently. 
> 
> If left distributes over right and inner op is commutative, then right will also distribute over left 
> too and vice versa. So Checking following 2 combinations if left distributes over right
>   try(a, b, c, d);
>   if (op' is commutative) {
>     try(a, b, d, c);
>   }
> and following 2 combination if right distributes ove left should be sufficient.
>   try(a, b, c, d);
>   if (op' is commutative) {
>     try(a, b, d, c);
>   }
> 
> Because for inner commutative operation
> 
> if try(a, b, c, d) fails for LeftDistributesOverRight then try(b, a, d, c) will fail for RightDistributesOverLeft
> if try(a, b, c, d) fails for RightDistributesOverLeft then try(b, a, d, c) will fail for LeftDistributesOverRight
> 
> similarly
> 
> if try(b, a, c, d) fails for LeftDistributesOverRight then try(a, b, d, c) will fail for RightDistributesOverLeft
> if try(a, b, c, d) fails for RightDistributesOverLeft then try(a, b, d, c) will fail for LeftDistributesOverRight
> 
> Am I missing something?
Please read last line in previous reply as
if try(b, a, c, d) fails for RightDistributesOverLeft then try(a, b, d, c) will fail for LeftDistributesOverRight

http://reviews.llvm.org/D3799






More information about the llvm-commits mailing list