Nikita Popov bec7181d5b [SCEVExpander] Don't use recursive expansion for ptr IV inc
Similar to the non-ptr case, directly create the getelementptr
instruction. Going through expandAddToGEP() no longer makes sense
with opaque pointers, where generating the necessary instruction
is trivial.

This avoids recursive expansion of (the SCEV of) StepV while the
IR is in an inconsistent state, in particular with an incomplete
IV phi node, which utilities may not be prepared to deal with.

Fixes https://github.com/llvm/llvm-project/issues/80954.
2024-02-07 11:27:26 +01:00

69 lines
2.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s
; Make sure this does not assert in SCEVExpander.
define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
; CHECK-LABEL: define void @test(
; CHECK-SAME: ptr [[P:%.*]], i8 [[ARG:%.*]], i64 [[ARG1:%.*]], i32 [[ARG2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[ARG]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ARG1]], -1
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ARG2]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ARG1]], [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[SEXT]]
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], -1
; CHECK-NEXT: [[TMP4:%.*]] = shl i64 [[TMP3]], 2
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LOOP_IDIOM_IV:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LATCH:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LATCH]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ARG2]], [[ENTRY]] ], [ [[ADD9:%.*]], [[LATCH]] ]
; CHECK-NEXT: [[TMP5:%.*]] = shl i64 [[INDVAR]], 2
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP4]], [[TMP5]]
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[LOOP_IDIOM_IV]], i8 0, i64 0, i1 false)
; CHECK-NEXT: br label [[LOOP2:%.*]]
; CHECK: loop2:
; CHECK-NEXT: [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP2]] ], [ 0, [[LOOP]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr [[P]], i64 [[IV]], i64 [[IV2]]
; CHECK-NEXT: [[IV2_NEXT]] = add i64 [[IV2]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[IV2_NEXT]], 0
; CHECK-NEXT: br i1 [[ICMP]], label [[LATCH]], label [[LOOP2]]
; CHECK: latch:
; CHECK-NEXT: [[ADD9]] = add nsw i32 [[PHI]], 1
; CHECK-NEXT: [[SEXT10:%.*]] = sext i32 [[PHI]] to i64
; CHECK-NEXT: [[ADD11:%.*]] = add i64 [[ADD]], [[SEXT10]]
; CHECK-NEXT: [[ADD12:%.*]] = add i64 [[ADD11]], [[SEXT]]
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[ADD12]], [[IV]]
; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LOOP_IDIOM_IV]], i64 [[TMP6]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
%sext = sext i8 %arg to i64
%add = add i64 %arg1, -1
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
%phi = phi i32 [ %arg2, %entry ], [ %add9, %latch ]
br label %loop2
loop2:
%iv2 = phi i64 [ %iv2.next, %loop2 ], [ 0, %loop ]
%gep = getelementptr [4 x i8], ptr %p, i64 %iv, i64 %iv2
store i8 0, ptr %gep, align 1
%iv2.next = add i64 %iv2, 1
%icmp = icmp eq i64 %iv2.next, 0
br i1 %icmp, label %latch, label %loop2
latch:
%add9 = add nsw i32 %phi, 1
%sext10 = sext i32 %phi to i64
%add11 = add i64 %add, %sext10
%add12 = add i64 %add11, %sext
%iv.next = add i64 %add12, %iv
br label %loop
}