[PATCH] Simplify (X ^ signbit) + C

Benjamin Kramer benny.kra at gmail.com
Mon May 6 13:37:42 PDT 2013


On 06.05.2013, at 22:15, David Majnemer <david.majnemer at gmail.com> wrote:

> Cases like (X - (1 << 31)) + C or (X ^ (1 << 31)) + C do not get constant folding.
> 
> The attached patch reassociates the instruction operands so that we get:
> (X - ((1 << 31) - C)).
> 
> Index: test/Transforms/InstCombine/sub-xor.ll
> ===================================================================
> --- test/Transforms/InstCombine/sub-xor.ll	(revision 181147)
> +++ test/Transforms/InstCombine/sub-xor.ll	(working copy)
> @@ -35,3 +35,13 @@
>  ; CHECK-NEXT: sub i32 73, %and
>  ; CHECK-NEXT: ret
>  }
> +
> +define i32 @test4(i32 %x) nounwind {
> +  %sub = xor i32 %x, 2147483648
> +  %add = add i32 %sub, 42
> +  ret i32 %add
> +
> +; CHECK: @test4
> +; CHECK-NEXT: add i32 %x, -2147483606
> +; CHECK-NEXT: ret
> +}
> Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp
> ===================================================================
> --- lib/Transforms/InstCombine/InstCombineAddSub.cpp	(revision 181147)
> +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp	(working copy)
> @@ -974,6 +974,10 @@
>            return BinaryOperator::CreateSub(ConstantExpr::getAdd(XorRHS, CI),
>                                             XorLHS);
>        }
> +      // (X ^ signbit) + C -> (X - (signbit - C))

Maybe add a comment that this is the canonical form for (X + signbit) + C.

Also the canonical form for subs with a constant is an add with a negative constant (instcombine would do this on the next iteration) so emitting something like (X + (signbit ^ C)) can avoid some work.

Otherwise LGTM.

- Ben

> +      if (XorRHS->getValue().isSignBit())
> +          return BinaryOperator::CreateSub(XorLHS,
> +                                           ConstantExpr::getSub(XorRHS, CI));
>      }
>    }
>  





More information about the llvm-commits mailing list