[LLVMdev] More info, was Help needed after hiatus

Eli Friedman eli.friedman at gmail.com
Sat May 17 13:57:23 PDT 2008


On Sat, May 17, 2008 at 11:34 AM, Richard Pennington <rich at pennware.com> wrote:
> If I run the optimizer (opt) on this code snippet with -std-compile-opts
> the optimizer hangs.
>
>
> ; ModuleID = 'test.ubc'
> target datalayout =
> "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-s0:0:64-f80:32:32"
> target triple = "i686-pc-linux-gnu"
>
> declare void @BZALLOC(i32)
>
> define void @f(i32) {
> entry:
>         %blockSize100k = alloca i32             ; <i32*> [#uses=2]
>         store i32 %0, i32* %blockSize100k
>         %n = alloca i32         ; <i32*> [#uses=2]
>         load i32* %blockSize100k                ; <i32>:1 [#uses=1]
>         store i32 %1, i32* %n
>         load i32* %n            ; <i32>:2 [#uses=1]
>         add i32 %2, 2           ; <i32>:3 [#uses=1]
>         mul i32 %3, ptrtoint (i32* getelementptr (i32* null, i32 1) to
> i32)             ; <i32>:4 [#uses=1]
>         call void @BZALLOC( i32 %4 )
>         br label %return
>
> return:         ; preds = %entry
>         ret void
> }

BTW, It's usually better to file a bug for this sort of thing.

The issue is around InstructionCombining:2507:
  // W*X + Y*Z --> W * (X+Z)  iff W == Y
  if (I.getType()->isIntOrIntVector()) {
    Value *W, *X, *Y, *Z;
    if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&
        match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) {

The issue starts with the lines:
        add i32 %2, 2           ; <i32>:3 [#uses=1]
        mul i32 %3, ptrtoint (i32* getelementptr (i32* null, i32 1) to
i32)             ; <i32>:4 [#uses=1]

Roughly, the multiplication gets distributed, resulting in something
like (loaded value) * (ptrtointexpr) + 2 * (ptrtointexpr).  This gets
matched by the match, which then reverses the transformation.  This,
of course, gets matched by the code to distribute the multiply,
resulting in a never-ending cycle.

A side note: I know I've seen suggestions that "ptrtoint (i32*
getelementptr (i32* null, i32 1) to i32)" is a suitable replacement
for sizeof, but if it is supposed to be legal, the documentation for
getelementptr should make that clear. I'm pretty sure the equivalent
C, "((int*)0)+1", has undefined behavior.

-Eli



More information about the llvm-dev mailing list