[llvm-commits] [llvm] r111665 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp test/Transforms/InstCombine/2010-08-19-StoreNarrowing.ll

Chris Lattner clattner at apple.com
Mon Aug 30 14:26:20 PDT 2010


On Aug 20, 2010, at 11:24 AM, Owen Anderson wrote:

> Author: resistor
> Date: Fri Aug 20 13:24:43 2010
> New Revision: 111665
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=111665&view=rev
> Log:
> Re-apply r111568 with a fix for the clang self-host.

Alright.  Please include a useful commit message though, so I don't have to go look at r111568 to find out what this does.  Some thoughts:

> @@ -473,6 +475,51 @@
> 
>   if (SI.isVolatile()) return 0;  // Don't hack volatile stores.
> 
> +  // Attempt to narrow sequences where we load a wide value, perform bitmasks
> +  // that only affect the low bits of it, and then store it back.  This 
> +  // typically arises from bitfield initializers in C++.

Why is this better to do in instcombine than dagcombine?  Unless the code is already type-unsafe, we typically do *not* want to do this in the mid-level.  In your specific testcase, there is a bitcast of the pointer and you're actually *improving* type safety, but there is nothing in the xform that encourages this.

> +  ConstantInt *CI1 =0, *CI2 = 0;
> +  Value *Ld = 0;
> +  if (getTargetData() &&
> +      match(SI.getValueOperand(),
> +            m_And(m_Or(m_Value(Ld), m_ConstantInt(CI1)), m_ConstantInt(CI2))) &&
> +      isa<LoadInst>(Ld) &&
> +      equivalentAddressValues(cast<LoadInst>(Ld)->getPointerOperand(), Ptr)) {

I don't see where you check to make sure you don't have something like:

x = load P
store 123 ->  Q    ;; might alias P!
x' = stuff(x)
store x' -> P

How do you know the loaded value hasn't been changed in memory?  Also, you don't check for a volatile load here.

> +    APInt OrMask = CI1->getValue();
> +    APInt AndMask = CI2->getValue();

No need to copy the APInt's.

> +    // Compute the prefix of the value that is unmodified by the bitmasking.
> +    unsigned LeadingAndOnes = AndMask.countLeadingOnes();
> +    unsigned LeadingOrZeros = OrMask.countLeadingZeros();
> +    unsigned Prefix = std::min(LeadingAndOnes, LeadingOrZeros);
> +    uint64_t NewWidth = AndMask.getBitWidth() - Prefix;
> +    while (NewWidth < AndMask.getBitWidth() &&
> +           getTargetData()->isIllegalInteger(NewWidth))
> +      NewWidth = NextPowerOf2(NewWidth);

It would be cleaner to just use TD directly instead of calling getTargetData() all over.

> +    // If we can find a power-of-2 prefix (and if the values we're working with
> +    // are themselves POT widths), then we can narrow the store.  We rely on
> +    // later iterations of instcombine to propagate the demanded bits to narrow
> +    // the other computations in the chain.
> +    if (NewWidth < AndMask.getBitWidth() &&
> +        getTargetData()->isLegalInteger(NewWidth)) {
> +      const Type *NewType = IntegerType::get(Ptr->getContext(), NewWidth);
> +      const Type *NewPtrType = PointerType::getUnqual(NewType);

This pointer type needs to be in the same address space as the original load/store.

> +++ llvm/trunk/test/Transforms/InstCombine/2010-08-19-StoreNarrowing.ll Fri Aug 20 13:24:43 2010

This should be folded into an existing testcase, and should not be dated.

> @@ -0,0 +1,21 @@
> +; RUN: opt -S -instcombine %s | not grep and

This should use filecheck.  Have you looked at what instcombine turns this into?  I suspect it isn't what you're expecting.

> +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
> +target triple = "x86_64-apple-darwin10.0.0"
> +
> +%class.A = type { i8, [3 x i8] }
> +
> +define void @_ZN1AC2Ev(%class.A* %this) nounwind ssp align 2 {

This should not use a mangled name.

-Chris

> +entry:
> +  %0 = bitcast %class.A* %this to i32*            ; <i32*> [#uses=5]
> +  %1 = load i32* %0, align 4                      ; <i32> [#uses=1]
> +  %2 = and i32 %1, -8                             ; <i32> [#uses=2]
> +  store i32 %2, i32* %0, align 4
> +  %3 = and i32 %2, -57                            ; <i32> [#uses=1]
> +  %4 = or i32 %3, 8                               ; <i32> [#uses=2]
> +  store i32 %4, i32* %0, align 4
> +  %5 = and i32 %4, -65                            ; <i32> [#uses=2]
> +  store i32 %5, i32* %0, align 4
> +  %6 = and i32 %5, -129                           ; <i32> [#uses=1]
> +  store i32 %6, i32* %0, align 4
> +  ret void
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list