1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" 5target triple = "x86_64-unknown-linux-gnu" 6 7; LIR'ing stores of pointers with address space 3 is fine, since 8; they're integral pointers. 9define void @f_0(ptr %ptr) { 10; CHECK-LABEL: @f_0( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[PTR:%.*]], i8 0, i64 80000, i1 false) 13; CHECK-NEXT: br label [[FOR_BODY:%.*]] 14; CHECK: for.body: 15; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[FOR_BODY]] ] 16; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr ptr addrspace(3), ptr [[PTR]], i64 [[INDVAR]] 17; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1 18; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 10000 19; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 20; CHECK: for.end: 21; CHECK-NEXT: ret void 22; 23 24entry: 25 br label %for.body 26 27for.body: 28 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 29 %arrayidx = getelementptr ptr addrspace(3), ptr %ptr, i64 %indvar 30 store ptr addrspace(3) null, ptr %arrayidx, align 4 31 %indvar.next = add i64 %indvar, 1 32 %exitcond = icmp eq i64 %indvar.next, 10000 33 br i1 %exitcond, label %for.end, label %for.body 34 35for.end: 36 ret void 37} 38 39; LIR'ing stores of pointers with address space 4 is not ok, since 40; they're non-integral pointers. NOTE: Zero is special value which 41; can be converted, if we add said handling here, convert this test 42; to use any non-null pointer. 43define void @f_1(ptr %ptr) { 44; CHECK-LABEL: @f_1( 45; CHECK-NEXT: entry: 46; CHECK-NEXT: br label [[FOR_BODY:%.*]] 47; CHECK: for.body: 48; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[FOR_BODY]] ] 49; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr ptr addrspace(4), ptr [[PTR:%.*]], i64 [[INDVAR]] 50; CHECK-NEXT: store ptr addrspace(4) null, ptr [[ARRAYIDX]], align 4 51; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1 52; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 10000 53; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 54; CHECK: for.end: 55; CHECK-NEXT: ret void 56; 57 58entry: 59 br label %for.body 60 61for.body: 62 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 63 %arrayidx = getelementptr ptr addrspace(4), ptr %ptr, i64 %indvar 64 store ptr addrspace(4) null, ptr %arrayidx, align 4 65 %indvar.next = add i64 %indvar, 1 66 %exitcond = icmp eq i64 %indvar.next, 10000 67 br i1 %exitcond, label %for.end, label %for.body 68 69for.end: 70 ret void 71} 72 73; Same as previous case, but vector of non-integral pointers 74define void @f_2(ptr %ptr) { 75; CHECK-LABEL: @f_2( 76; CHECK-NEXT: entry: 77; CHECK-NEXT: br label [[FOR_BODY:%.*]] 78; CHECK: for.body: 79; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[FOR_BODY]] ] 80; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr ptr addrspace(4), ptr [[PTR:%.*]], i64 [[INDVAR]] 81; CHECK-NEXT: store <2 x ptr addrspace(4)> zeroinitializer, ptr [[ARRAYIDX]], align 8 82; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 2 83; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 10000 84; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 85; CHECK: for.end: 86; CHECK-NEXT: ret void 87; 88entry: 89 br label %for.body 90 91for.body: 92 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 93 %arrayidx = getelementptr ptr addrspace(4), ptr %ptr, i64 %indvar 94 store <2 x ptr addrspace(4)> zeroinitializer, ptr %arrayidx, align 8 95 %indvar.next = add i64 %indvar, 2 96 %exitcond = icmp eq i64 %indvar.next, 10000 97 br i1 %exitcond, label %for.end, label %for.body 98 99for.end: 100 ret void 101} 102