[llvm-commits] [PATCH] Teach IRBuilder about simplifying BinOp(Value, Constant)

Török Edwin edwintorok at gmail.com
Sun Dec 28 12:07:02 PST 2008


I have a pass that produces lots of and,or,xor where one of the operands
is a constant (0 or all ones).
Initially I thought to run instcombine afterwards to clean up, but now I
think  it is more efficient to not create those instructions in the
first place:
why create possibly hundreds of instructions just to delete them later.

I could do this "simplification" in my pass, but I thought that a better
place is IRBuilder, which already does constant folding by default
(when both operands are constant).  Another alternative would be a
utility function SimplifyInstruction (similar to ConstantFoldInstruction).

Which one is more appropriate?

The attached patch adds another template parameter (that defaults to a
no-op implementation) to simplify BinOps where one operand is constant.

There is also a BinOpSimplifier class in my patch that handles some very
simple (and common for me) cases:
 * I have only implemented very simple cases, the more cases belong to
instcombine (and AFAICT they are there already)
 * if instruction already exists in BB before or at insertion point,
reuse it
    If BinOpSimplifier ever becomes the default for IRBuilder, this
could cause problems if somebody inserts an instruction using IRBuilder,
       and later uses RAUW if !isa<Constant>, because it can potentially
replace more than he thought of!
 * if the outcome of a binop is known to be a constant, return the constant:
       and X, 0 -> 0; and X, ~0 -> X; or X, 0 -> X; or X, ~0; xor X, 0 -> X;
 * simplify chained XORs with same constant,:
    If we want to create xor %1, C; and there is a "%1 = xor %0,  C",
then return %0

While we're here I also implemented:
 * add X, 0 -> X
 * sub X, 0 -> X
 * mul X, 0 -> 0
 * mul X, 1 -> X
 * udiv/sdiv 0, X -> 0
 * udiv/sdiv X, 1 -> X
 * urem X, 1 -> 0

I haven't implemented shifts, because I am not sure how complicated we'd
want to make this: use ComputeMaskedBits, and make decision based on
that, or
just simplify shift by 0, and shift > bitwidth?

I am submitting this for discussion, and to see if I am going into the
right direction, the patch currently lacks a test case for example.

What do you think?
Is this patch acceptable as a default no-op (using NoSimplifier in
Does anybody want this to be default on?

I can think of clang as a possible user (besides my pass). llvm-gcc -O0
appears to do this kind of simplification by default.

Best regards,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: simplifier.patch
Type: text/x-patch
Size: 16322 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20081228/c2e10f5f/attachment.bin>

More information about the llvm-commits mailing list