[LLVMbugs] [Bug 14173] New: GEP scaling not combined with explicit scaling

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Oct 25 01:26:42 PDT 2012


http://llvm.org/bugs/show_bug.cgi?id=14173

             Bug #: 14173
           Summary: GEP scaling not combined with explicit scaling
           Product: new-bugs
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: baldrick at free.fr
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Consider compiling this on x86-64 with clang:

int foo(int *A, int N) {
  return A[2*N];
}

It multiplies N by 8 and offsets the pointer by that many bytes.  The
offset consists of an explicit multiplication by 2, and an implicit
multiplication by 4 (aka sizeof(int)) via the array access.  However
these two multiplications aren't combined into one in the final assembler:

The LLVM IR is

define i32 @foo(i32* nocapture %A, i32 %N) nounwind uwtable readonly {
entry:
  %mul = shl nsw i32 %N, 1
  %idxprom = sext i32 %mul to i64
  %arrayidx = getelementptr inbounds i32* %A, i64 %idxprom
  %0 = load i32* %arrayidx, align 4
  ret i32 %0
}

which codegens to

        addl    %esi, %esi           ; multiply by 2
        movslq  %esi, %rax
        movl    (%rdi,%rax,4), %eax  ; multiply by 4
        ret

The LLVM IR could be turned into

define i32 @foo(i32* nocapture %A, i32 %N) nounwind uwtable readonly {
entry:
  %Nprom = sext i32 %N to i64
  %mul = shl nsw i64 %Nprom, 1
  %arrayidx = getelementptr inbounds i32* %A, i64 %mul
  %0 = load i32* %arrayidx, align 4
  ret i32 %0
}

(the transform is correct because of the nsw flag on the multiplication) which
codegens to

        movslq  %esi, %rax
        movl    (%rdi,%rax,8), %eax ; multiply by 8
        ret

There are several possible strategies for fixing this.

(1) At the IR level, when a computation is feeding a GEP as an offset, could
try
to promote the entire expression to intptrtype, producing the second example of
LLVM IR above.
(2) At the IR level, when an expression is feeding a GEP, could try to pull any
*constant* factors through casts like the sext, rather than arbitrary factors.
(3) Same kind of thing as (1) or (2) but during CodeGenPrepare.
(4) Same kind of thing as (1) or (2) but as a DAG combine.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list