[llvm-bugs] [Bug 47627] New: loop-reroll rerolls loops with unrerollable instructions

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Sep 23 05:31:22 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47627

            Bug ID: 47627
           Summary: loop-reroll rerolls loops with unrerollable
                    instructions
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: t-kawashima at fujitsu.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 23995
  --> https://bugs.llvm.org/attachment.cgi?id=23995&action=edit
unrerollable1.ll; IR with unrerollable instructions

Problem Description
===================

loop-reroll rerolls loops with unrerollable instructions.

See the following IR (same as the attached one).

--------------------------------
define dso_local void @foo([2 x i32]* nocapture %a) local_unnamed_addr {
entry:
  br label %loop

loop:
  ; base instruction
  %indvars = phi i64 [ 0, %entry ], [ %indvars.next, %loop ]

  ; unrerollable instructions
  %stptrx = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %indvars, i64
0
  store i32 999, i32* %stptrx, align 4

  ; extra simple arithmetic operations
  %plus20 = add nuw nsw i64 %indvars, 20
  %plus10 = add nuw nsw i64 %indvars, 10

  ; root instruction 0
  %ldptr0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus20, i64 0
  %value0 = load i32, i32* %ldptr0, align 4
  %stptr0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus10, i64 0
  store i32 %value0, i32* %stptr0, align 4

  ; root instruction 1
  %ldptr1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus20, i64 1
  %value1 = load i32, i32* %ldptr1, align 4
  %stptr1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus10, i64 1
  store i32 %value1, i32* %stptr1, align 4

  ; latch
  %indvars.next = add nuw nsw i64 %indvars, 1
  %exitcond = icmp eq i64 %indvars.next, 5
  br i1 %exitcond, label %exit, label %loop

exit:
  ret void
}
--------------------------------

This IR is generated from the following C program.

--------------------------------
void foo(int a[][2]) {
  for (int i = 0; i < 5; i++) {
    a[i][0] = 999;
    a[10+i][0] = a[20+i][0];
    a[10+i][1] = a[20+i][1];
  }
}
--------------------------------

This program is unrerollable because of the existence of
`a[i][0] = 999`. However, `opt -loop-reroll` rerolls this to
the following IR.

--------------------------------
define dso_local void @foo([2 x i32]* nocapture %a) local_unnamed_addr {
entry:
  br label %loop

loop:
  %indvars = phi i64 [ 0, %entry ], [ %indvars.next, %loop ]
  %scevgep1 = getelementptr [2 x i32], [2 x i32]* %a, i64 20, i64 %indvars
  %scevgep = getelementptr [2 x i32], [2 x i32]* %a, i64 10, i64 %indvars
  %stptrx = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %indvars, i64
0
  store i32 999, i32* %stptrx, align 4
  %value0 = load i32, i32* %scevgep1, align 4
  store i32 %value0, i32* %scevgep, align 4
  %indvars.next = add nuw nsw i64 %indvars, 1
  %exitcond2 = icmp eq i64 %indvars, 9
  br i1 %exitcond2, label %exit, label %loop

exit:
  ret void
}
--------------------------------

This IR is equivalent to the following C program.

--------------------------------
void foo(int a[][2]) {
  for (int i = 0; i < 10; i++) {
    a[i][0] = 999;
    a[10][i] = a[20][i];
  }
}
--------------------------------

a[5][0], a[6][0], ..., a[9][0] should not be updated, but they
are updated. It's a bug.

I confirmed this problem with at least the latest master branch
(commit 10092291d7a) and LLVM 7.1.0.

This problem is not limited to two dimensional array. Also,
not limited to a store operation. Compiling the following C
programs with `clang -O1 -freroll-loops` also has the problem.

--------------------------------
void bar(int x);

void foo(int a[]) {
  #pragma clang loop unroll(disable)
  for (int i = 0; i < 5; i++) {
    bar(a[i]);
    a[20+2*i+0] = a[40+2*i+0];
    a[20+2*i+1] = a[40+2*i+1];
  }
}
--------------------------------

--------------------------------
struct x {
  int m1;
  int m2;
};

void foo(struct x *a) {
  #pragma clang loop unroll(disable)
  for (int i = 0; i < 5; i++) {
    a[i].m1 = 999;
    a[10+i].m1 = a[20+i].m1;
    a[10+i].m2 = a[20+i].m2;
  }
}
--------------------------------

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200923/e5c7d889/attachment.html>


More information about the llvm-bugs mailing list