LSR pass

Hi,

I would like some help regarding the LSR pass. It seems that it likes to duplicate address calculations as in the case above, which is highly undesirable on my target.

I wonder if there is any way to tell LSR to not duplicate the code in cases like this? Or could I perhaps run CSE after LSR again?
What is the logic behind this transformation? It seems that a LSR pass should not insert a multiplication, generally..?

Thanks,
Jonas

  %_tmp44 = ptrtoint i16* par1 to i16
  %_tmp51 = ptrtoint i16* par2 to i16
...
inside loop:
*** IR Dump After Canonicalize natural loops ***
bb7: (header) ; preds = %bb7.lr.ph, %bb11

  %_tmp39 = sub i16 %_tmp35, %_tmp38
  %2 = mul i16 %_tmp39, -10
  %_tmp41 = add i16 %2, %subframeCount.12.014

  %_tmp45 = add i16 %_tmp41, %_tmp44
  %_tmp46 = inttoptr i16 %_tmp45 to i16*
  %_tmp47 = load i16* %_tmp46, align 1

bb8: ; preds = %bb7
  %_tmp52 = add i16 %_tmp41, %_tmp51
  %_tmp53 = inttoptr i16 %_tmp52 to i16*
  %_tmp54 = load i16* %_tmp53, align 1

...
  br i1 %_tmp64, label %bb7, label %bb13.loopexit
(latch)

*** IR Dump After Loop Strength Reduction ***
bb7: ; preds = %bb7.lr.ph, %bb11

  %_tmp39 = sub i16 %_tmp35, %_tmp38
  %2 = mul i16 %_tmp39, -10
  %3 = add i16 %_tmp44, %subframeCount.12.014
  %4 = add i16 %3, %2
  %_tmp46 = inttoptr i16 %4 to i16*
  %_tmp47 = load i16* %_tmp46, align 1

bb8: ; preds = %bb7
  %5 = sub i16 %_tmp35, %_tmp38
  %6 = mul i16 %5, -10
  %7 = add i16 %_tmp51, %subframeCount.12.014
  %8 = add i16 %7, %6
  %_tmp53 = inttoptr i16 %8 to i16*
  %_tmp54 = load i16* %_tmp53, align 1

...
  br i1 %_tmp64, label %bb7, label %bb13.loopexit

From: "Jonas Paulsson" <jonas.paulsson@ericsson.com>
To: llvmdev@cs.uiuc.edu
Sent: Monday, November 26, 2012 1:40:24 PM
Subject: [LLVMdev] LSR pass

Hi,

I would like some help regarding the LSR pass. It seems that it likes
to duplicate address calculations as in the case above, which is
highly undesirable on my target.

I wonder if there is any way to tell LSR to not duplicate the code in
cases like this? Or could I perhaps run CSE after LSR again?

What is the logic behind this transformation? It seems that a LSR
pass should not insert a multiplication, generally..?

I believe that the general logic behind this is that on many targets these extra instructions are absorbed into the 'addressing mode' of the user instructions. Does your target support any non-trivial addressing modes?

-Hal

Hi,

The target supports indexing by register or immediate. Multiplications are not supported by any load / store instructions. Would it be possible to make LSR aware of this?

Thanks,

Jonas Paulsson

LSR queries TargetLowering::isLegalAddressingMode() to find out if a particular addressing mode is legal:

/// isLegalAddressingMode - Return true if the addressing mode represented by
/// AM is legal for this target, for a load/store of the specified type.
/// The type may be VoidTy, in which case only return true if the addressing
/// mode is legal for a load/store of any legal type.

You'll need to implement this hook in your target.