blob: a15db620e00820e88c14acb66faa9daab392efca [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -p loop-idiom -S %s | FileCheck %s
target datalayout = "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
declare void @foo()
declare void @bar()
define void @scev_expand_ptrtoint(i8 %x, ptr %start) {
; CHECK-LABEL: define void @scev_expand_ptrtoint(
; CHECK-SAME: i8 [[X:%.*]], ptr [[START:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[START1:%.*]] = ptrtoint ptr [[START]] to i64
; CHECK-NEXT: br label %[[LOOP_1_HEADER:.*]]
; CHECK: [[LOOP_1_HEADER]]:
; CHECK-NEXT: [[PTR_IV_1:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_1_NEXT:%.*]], %[[LOOP_1_LATCH:.*]] ]
; CHECK-NEXT: [[C:%.*]] = icmp ule i8 [[X]], 1
; CHECK-NEXT: br i1 [[C]], label %[[LOOP_1_LATCH]], label %[[MIDDLE:.*]]
; CHECK: [[LOOP_1_LATCH]]:
; CHECK-NEXT: [[PTR_IV_1_NEXT]] = getelementptr i8, ptr [[PTR_IV_1]], i64 1
; CHECK-NEXT: br label %[[LOOP_1_HEADER]]
; CHECK: [[MIDDLE]]:
; CHECK-NEXT: [[PTR_IV_1_LCSSA:%.*]] = phi ptr [ [[PTR_IV_1]], %[[LOOP_1_HEADER]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X]], 0
; CHECK-NEXT: [[CMP_EXT:%.*]] = zext i1 [[CMP]] to i64
; CHECK-NEXT: [[GEP_START:%.*]] = getelementptr i8, ptr [[PTR_IV_1_LCSSA]], i64 [[CMP_EXT]]
; CHECK-NEXT: br label %[[LOOP_2_HEADER:.*]]
; CHECK: [[LOOP_2_HEADER]]:
; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], %[[LOOP_2_LATCH:.*]] ], [ 0, %[[MIDDLE]] ]
; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[GEP_START]], %[[MIDDLE]] ], [ [[PTR_IV_2_NEXT:%.*]], %[[LOOP_2_LATCH]] ]
; CHECK-NEXT: switch i8 [[X]], label %[[LOOP_2_LATCH]] [
; CHECK-NEXT: i8 1, label %[[LOOP_3_PREHEADER:.*]]
; CHECK-NEXT: i8 4, label %[[LOOP_3_PREHEADER]]
; CHECK-NEXT: ]
; CHECK: [[LOOP_3_PREHEADER]]:
; CHECK-NEXT: [[INDVAR_LCSSA:%.*]] = phi i64 [ [[INDVAR]], %[[LOOP_2_HEADER]] ], [ [[INDVAR]], %[[LOOP_2_HEADER]] ]
; CHECK-NEXT: [[PTR_IV_2_LCSSA:%.*]] = phi ptr [ [[PTR_IV_2]], %[[LOOP_2_HEADER]] ], [ [[PTR_IV_2]], %[[LOOP_2_HEADER]] ]
; CHECK-NEXT: [[TMP0:%.*]] = sub i64 1, [[START1]]
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR_IV_1_LCSSA]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[TMP0]]
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[CMP_EXT]], [[TMP2]]
; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[INDVAR_LCSSA]], [[TMP4]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[START]], i64 [[TMP5]]
; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr [[SCEVGEP]])
; CHECK-NEXT: br label %[[LOOP_3:.*]]
; CHECK: [[LOOP_2_LATCH]]:
; CHECK-NEXT: [[PTR_IV_2_NEXT]] = getelementptr i8, ptr [[PTR_IV_2]], i64 1
; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1
; CHECK-NEXT: br label %[[LOOP_2_HEADER]]
; CHECK: [[LOOP_3]]:
; CHECK-NEXT: [[IV_3:%.*]] = phi i64 [ [[IV_3_NEXT:%.*]], %[[LOOP_3]] ], [ 1, %[[LOOP_3_PREHEADER]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR_IV_2_LCSSA]], i64 [[IV_3]]
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[GEP]], align 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[TMP6]], 0
; CHECK-NEXT: [[IV_3_NEXT]] = add i64 [[IV_3]], 1
; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[LOOP_3]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %loop.1.header
loop.1.header:
%ptr.iv.1 = phi ptr [ %start, %entry ], [ %ptr.iv.1.next, %loop.1.latch ]
%c = icmp ule i8 %x, 1
br i1 %c, label %loop.1.latch, label %middle
loop.1.latch:
%ptr.iv.1.next = getelementptr i8, ptr %ptr.iv.1, i64 1
br label %loop.1.header
middle:
%cmp = icmp eq i8 %x, 0
%cmp.ext = zext i1 %cmp to i64
%gep.start = getelementptr i8, ptr %ptr.iv.1, i64 %cmp.ext
br label %loop.2.header
loop.2.header:
%ptr.iv.2 = phi ptr [ %gep.start, %middle ], [ %ptr.iv.2.next, %loop.2.latch ]
switch i8 %x, label %loop.2.latch [
i8 1, label %loop.3
i8 4, label %loop.3
]
loop.2.latch:
%ptr.iv.2.next = getelementptr i8, ptr %ptr.iv.2, i64 1
br label %loop.2.header
loop.3:
%iv.3 = phi i64 [ 1, %loop.2.header ], [ 1, %loop.2.header ], [ %iv.3.next, %loop.3 ]
%gep = getelementptr i8, ptr %ptr.iv.2, i64 %iv.3
%1 = load i8, ptr %gep, align 1
%ec = icmp eq i8 %1, 0
%iv.3.next = add i64 %iv.3, 1
br i1 %ec, label %exit, label %loop.3
exit:
ret void
}
declare i1 @cond()
define ptr @test_lcssa_reuse_preserve_lcssa() {
; CHECK-LABEL: define ptr @test_lcssa_reuse_preserve_lcssa() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[LOOP_0_HEADER:.*]]
; CHECK: [[LOOP_0_HEADER]]:
; CHECK-NEXT: br label %[[LOOP_1:.*]]
; CHECK: [[LOOP_1]]:
; CHECK-NEXT: [[IV_1:%.*]] = phi ptr [ null, %[[LOOP_0_HEADER]] ], [ [[IV_1_NEXT:%.*]], %[[LOOP_1]] ]
; CHECK-NEXT: [[IV_1_NEXT]] = getelementptr i8, ptr [[IV_1]], i64 1
; CHECK-NEXT: [[EC_1:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[EC_1]], label %[[THEN:.*]], label %[[LOOP_1]]
; CHECK: [[THEN]]:
; CHECK-NEXT: [[IV_1_LCSSA1:%.*]] = phi ptr [ [[IV_1]], %[[LOOP_1]] ]
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C_2]], label %[[LOOP_2_PREHEADER:.*]], label %[[LOOP_0_LATCH:.*]]
; CHECK: [[LOOP_2_PREHEADER]]:
; CHECK-NEXT: [[IV_1_LCSSA:%.*]] = phi ptr [ [[IV_1_LCSSA1]], %[[THEN]] ]
; CHECK-NEXT: [[IV_1_LCSSA_LCSSA:%.*]] = phi ptr [ [[IV_1_LCSSA1]], %[[THEN]] ]
; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr null)
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[IV_1_LCSSA]], i64 1
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[TMP0]], i64 [[STRLEN]]
; CHECK-NEXT: br label %[[LOOP_2:.*]]
; CHECK: [[LOOP_2]]:
; CHECK-NEXT: [[IV_2:%.*]] = phi ptr [ [[RES:%.*]], %[[LOOP_2]] ], [ [[IV_1_LCSSA_LCSSA]], %[[LOOP_2_PREHEADER]] ]
; CHECK-NEXT: [[RES]] = getelementptr i8, ptr [[IV_2]], i64 1
; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[IV_1_LCSSA_LCSSA]], align 1
; CHECK-NEXT: [[EC_2:%.*]] = icmp eq i8 [[L]], 0
; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[LOOP_2]]
; CHECK: [[LOOP_0_LATCH]]:
; CHECK-NEXT: br label %[[LOOP_0_HEADER]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret ptr [[SCEVGEP]]
;
entry:
br label %loop.0.header
loop.0.header:
br label %loop.1
loop.1:
%iv.1 = phi ptr [ null, %loop.0.header ], [ %iv.1.next, %loop.1 ]
%iv.1.next = getelementptr i8, ptr %iv.1, i64 1
%ec.1 = call i1 @cond()
br i1 %ec.1, label %then, label %loop.1
then:
%c.2 = call i1 @cond()
br i1 %c.2, label %loop.2, label %loop.0.latch
loop.2:
%iv.2 = phi ptr [ %res, %loop.2 ], [ %iv.1, %then ]
%res = getelementptr i8, ptr %iv.2, i64 1
%l = load i8, ptr %iv.1, align 1
%ec.2 = icmp eq i8 %l, 0
br i1 %ec.2, label %exit, label %loop.2
loop.0.latch:
br label %loop.0.header
exit:
ret ptr %res
}
; Test case for https://github.com/llvm/llvm-project/issues/155287.
; Make sure we don't crash when trying to construct a PtrToInt SCEV expression
; results in SCEVCouldNotCompute.
define void @phi_ptr_addressspace_ptrtoint_fail(ptr addrspace(1) %arg) {
; CHECK-LABEL: define void @phi_ptr_addressspace_ptrtoint_fail(
; CHECK-SAME: ptr addrspace(1) [[ARG:%.*]]) {
; CHECK-NEXT: [[BB:.*]]:
; CHECK-NEXT: br label %[[LOOP_1:.*]]
; CHECK: [[LOOP_1]]:
; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[ADD5:%.*]], %[[LOOP_1]] ]
; CHECK-NEXT: [[ADD5]] = add i64 [[IV_1]], 1
; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i16, ptr addrspace(1) [[ARG]], i64 [[ADD5]]
; CHECK-NEXT: br i1 false, label %[[LOOP_1]], label %[[LOOP_2_PH:.*]]
; CHECK: [[LOOP_2_PH]]:
; CHECK-NEXT: [[IV_1_LCSSA1:%.*]] = phi i64 [ [[IV_1]], %[[LOOP_1]] ]
; CHECK-NEXT: [[IV_1_LCSSA:%.*]] = phi i64 [ [[IV_1]], %[[LOOP_1]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi ptr addrspace(1) [ [[GETELEMENTPTR]], %[[LOOP_1]] ]
; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i64 [[IV_1_LCSSA1]], 2
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr addrspace(1) [[ARG]], i64 [[TMP0]]
; CHECK-NEXT: call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 [[SCEVGEP]], i8 0, i64 8, i1 false)
; CHECK-NEXT: br label %[[LOOP_2_HEADER:.*]]
; CHECK: [[LOOP_2_HEADER]]:
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_1_LCSSA]], %[[LOOP_2_PH]] ], [ [[IV_2_NEXT:%.*]], %[[LOOP_2_LATCH:.*]] ]
; CHECK-NEXT: [[GREP_ARG:%.*]] = getelementptr i32, ptr addrspace(1) [[ARG]], i64 [[IV_2]]
; CHECK-NEXT: [[EC:%.*]] = icmp ult i64 [[IV_2]], 1
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP_2_LATCH]], label %[[EXIT:.*]]
; CHECK: [[LOOP_2_LATCH]]:
; CHECK-NEXT: [[IV_2_NEXT]] = add i64 [[IV_2]], 1
; CHECK-NEXT: br label %[[LOOP_2_HEADER]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
bb:
br label %loop.1
loop.1:
%iv.1 = phi i64 [ 0, %bb ], [ %add5, %loop.1]
%add5 = add i64 %iv.1, 1
%getelementptr = getelementptr i16, ptr addrspace(1) %arg, i64 %add5
br i1 false, label %loop.1, label %loop.2.ph
loop.2.ph:
%phi = phi ptr addrspace(1) [ %getelementptr, %loop.1]
br label %loop.2.header
loop.2.header:
%iv.2 = phi i64 [ %iv.1, %loop.2.ph ], [ %iv.2.next, %loop.2.latch ]
%grep.arg = getelementptr i32, ptr addrspace(1) %arg, i64 %iv.2
store i32 0, ptr addrspace(1) %grep.arg, align 4
%ec = icmp ult i64 %iv.2, 1
br i1 %ec, label %loop.2.latch, label %exit
loop.2.latch:
%iv.2.next = add i64 %iv.2, 1
br label %loop.2.header
exit:
ret void
}