1ddd4ed99SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2ddd4ed99SPhilip Reames; RUN: opt < %s -loop-reduce -S | FileCheck %s 3ddd4ed99SPhilip Reames 4ddd4ed99SPhilip Reamestarget datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" 5ddd4ed99SPhilip Reamestarget triple = "riscv64" 6ddd4ed99SPhilip Reames 7ddd4ed99SPhilip Reames 8ddd4ed99SPhilip Reamesdefine void @icmp_zero(i64 %N, ptr %p) { 9ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero( 10ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 11ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 12ddd4ed99SPhilip Reames; CHECK: vector.body: 13ddd4ed99SPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[N:%.*]], [[ENTRY:%.*]] ] 14ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 15ddd4ed99SPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 16ddd4ed99SPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 17ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 18ddd4ed99SPhilip Reames; CHECK: exit: 19ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 20ddd4ed99SPhilip Reames; 21ddd4ed99SPhilip Reamesentry: 22ddd4ed99SPhilip Reames br label %vector.body 23ddd4ed99SPhilip Reames 24ddd4ed99SPhilip Reamesvector.body: 25ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 26ddd4ed99SPhilip Reames store i64 0, ptr %p 27ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 28ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %N 29ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 30ddd4ed99SPhilip Reames 31ddd4ed99SPhilip Reamesexit: 32ddd4ed99SPhilip Reames ret void 33ddd4ed99SPhilip Reames} 34ddd4ed99SPhilip Reames 35ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nonzero_con(i64 %N, ptr %p) { 36ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nonzero_con( 37ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 38ddd4ed99SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], 16 39ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 40ddd4ed99SPhilip Reames; CHECK: vector.body: 41ddd4ed99SPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 42ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 43ddd4ed99SPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 44ddd4ed99SPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 45ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 46ddd4ed99SPhilip Reames; CHECK: exit: 47ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 48ddd4ed99SPhilip Reames; 49ddd4ed99SPhilip Reamesentry: 50ddd4ed99SPhilip Reames %urem = urem i64 %N, 16 51ddd4ed99SPhilip Reames br label %vector.body 52ddd4ed99SPhilip Reames 53ddd4ed99SPhilip Reamesvector.body: 54ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 55ddd4ed99SPhilip Reames store i64 0, ptr %p 56ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 57ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %urem 58ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 59ddd4ed99SPhilip Reames 60ddd4ed99SPhilip Reamesexit: 61ddd4ed99SPhilip Reames ret void 62ddd4ed99SPhilip Reames} 63ddd4ed99SPhilip Reames 64ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_invariant(i64 %N, i64 %M, ptr %p) { 65ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_invariant( 66ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 67ddd4ed99SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]] 68ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 69ddd4ed99SPhilip Reames; CHECK: vector.body: 70*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 71ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 72*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 73*6ab686ebSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 74ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 75ddd4ed99SPhilip Reames; CHECK: exit: 76ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 77ddd4ed99SPhilip Reames; 78ddd4ed99SPhilip Reamesentry: 79ddd4ed99SPhilip Reames %urem = urem i64 %N, %M 80ddd4ed99SPhilip Reames br label %vector.body 81ddd4ed99SPhilip Reames 82ddd4ed99SPhilip Reamesvector.body: 83ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 84ddd4ed99SPhilip Reames store i64 0, ptr %p 85ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 86ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %urem 87ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 88ddd4ed99SPhilip Reames 89ddd4ed99SPhilip Reamesexit: 90ddd4ed99SPhilip Reames ret void 91ddd4ed99SPhilip Reames} 92ddd4ed99SPhilip Reames 93d767b392SPhilip Reames; We have to be careful here as SCEV can only compute a subtraction from 94d767b392SPhilip Reames; two pointers with the same base. If we hide %end inside a unknown, we 95d767b392SPhilip Reames; can no longer compute the subtract. 96d767b392SPhilip Reamesdefine void @icmp_zero_urem_invariant_ptr(i64 %N, i64 %M, ptr %p) { 97d767b392SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_invariant_ptr( 98d767b392SPhilip Reames; CHECK-NEXT: entry: 99d767b392SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]] 100d767b392SPhilip Reames; CHECK-NEXT: [[END:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 [[UREM]] 101d767b392SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 102d767b392SPhilip Reames; CHECK: vector.body: 103d767b392SPhilip Reames; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[P]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[VECTOR_BODY]] ] 104d767b392SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P]], align 8 105d767b392SPhilip Reames; CHECK-NEXT: [[IV_NEXT]] = getelementptr i64, ptr [[IV]], i64 1 106d767b392SPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]] 107d767b392SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 108d767b392SPhilip Reames; CHECK: exit: 109d767b392SPhilip Reames; CHECK-NEXT: ret void 110d767b392SPhilip Reames; 111d767b392SPhilip Reamesentry: 112d767b392SPhilip Reames %urem = urem i64 %N, %M 113d767b392SPhilip Reames %end = getelementptr i64, ptr %p, i64 %urem 114d767b392SPhilip Reames br label %vector.body 115d767b392SPhilip Reames 116d767b392SPhilip Reamesvector.body: 117d767b392SPhilip Reames %iv = phi ptr [ %p, %entry ], [ %iv.next, %vector.body ] 118d767b392SPhilip Reames store i64 0, ptr %p 119d767b392SPhilip Reames %iv.next = getelementptr i64, ptr %iv, i64 1 120d767b392SPhilip Reames %done = icmp eq ptr %iv.next, %end 121d767b392SPhilip Reames br i1 %done, label %exit, label %vector.body 122d767b392SPhilip Reames 123d767b392SPhilip Reamesexit: 124d767b392SPhilip Reames ret void 125d767b392SPhilip Reames} 126d767b392SPhilip Reames 127ddd4ed99SPhilip Reames; Negative test - We can not hoist because we don't know value of %M. 128ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nohoist(i64 %N, i64 %M, ptr %p) { 129ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nohoist( 130ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 131ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 132ddd4ed99SPhilip Reames; CHECK: vector.body: 133ddd4ed99SPhilip Reames; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[VECTOR_BODY]] ] 134ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 135ddd4ed99SPhilip Reames; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 2 136ddd4ed99SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]] 137ddd4ed99SPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[IV_NEXT]], [[UREM]] 138ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 139ddd4ed99SPhilip Reames; CHECK: exit: 140ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 141ddd4ed99SPhilip Reames; 142ddd4ed99SPhilip Reamesentry: 143ddd4ed99SPhilip Reames br label %vector.body 144ddd4ed99SPhilip Reames 145ddd4ed99SPhilip Reamesvector.body: 146ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 147ddd4ed99SPhilip Reames store i64 0, ptr %p 148ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 149ddd4ed99SPhilip Reames %urem = urem i64 %N, %M 150ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %urem 151ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 152ddd4ed99SPhilip Reames 153ddd4ed99SPhilip Reamesexit: 154ddd4ed99SPhilip Reames ret void 155ddd4ed99SPhilip Reames} 156ddd4ed99SPhilip Reames 157ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nonzero(i64 %N, i64 %M, ptr %p) { 158ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nonzero( 159ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 160ddd4ed99SPhilip Reames; CHECK-NEXT: [[NONZERO:%.*]] = add nuw i64 [[M:%.*]], 1 161ddd4ed99SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[NONZERO]] 162ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 163ddd4ed99SPhilip Reames; CHECK: vector.body: 1643bc09c7dSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 165ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 1663bc09c7dSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 1673bc09c7dSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 168ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 169ddd4ed99SPhilip Reames; CHECK: exit: 170ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 171ddd4ed99SPhilip Reames; 172ddd4ed99SPhilip Reamesentry: 173ddd4ed99SPhilip Reames %nonzero = add nuw i64 %M, 1 174ddd4ed99SPhilip Reames %urem = urem i64 %N, %nonzero 175ddd4ed99SPhilip Reames br label %vector.body 176ddd4ed99SPhilip Reames 177ddd4ed99SPhilip Reamesvector.body: 178ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 179ddd4ed99SPhilip Reames store i64 0, ptr %p 180ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 181ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %urem 182ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 183ddd4ed99SPhilip Reames 184ddd4ed99SPhilip Reamesexit: 185ddd4ed99SPhilip Reames ret void 186ddd4ed99SPhilip Reames} 187ddd4ed99SPhilip Reames 188ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_vscale(i64 %N, ptr %p) { 189ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale( 190ddd4ed99SPhilip Reames; CHECK-NEXT: entry: 191ddd4ed99SPhilip Reames; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 192ddd4ed99SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[VSCALE]] 193ddd4ed99SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 194ddd4ed99SPhilip Reames; CHECK: vector.body: 1953bc09c7dSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 196ddd4ed99SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 1973bc09c7dSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 1983bc09c7dSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 199ddd4ed99SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 200ddd4ed99SPhilip Reames; CHECK: exit: 201ddd4ed99SPhilip Reames; CHECK-NEXT: ret void 202ddd4ed99SPhilip Reames; 203ddd4ed99SPhilip Reamesentry: 204ddd4ed99SPhilip Reames %vscale = call i64 @llvm.vscale.i64() 205ddd4ed99SPhilip Reames %urem = urem i64 %N, %vscale 206ddd4ed99SPhilip Reames br label %vector.body 207ddd4ed99SPhilip Reames 208ddd4ed99SPhilip Reamesvector.body: 209ddd4ed99SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 210ddd4ed99SPhilip Reames store i64 0, ptr %p 211ddd4ed99SPhilip Reames %iv.next = add i64 %iv, 2 212ddd4ed99SPhilip Reames %done = icmp eq i64 %iv.next, %urem 213ddd4ed99SPhilip Reames br i1 %done, label %exit, label %vector.body 214ddd4ed99SPhilip Reames 215ddd4ed99SPhilip Reamesexit: 216ddd4ed99SPhilip Reames ret void 217ddd4ed99SPhilip Reames} 218ddd4ed99SPhilip Reames 219c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_mul8(i64 %N, ptr %p) { 220c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_mul8( 221c0df6bc9SPhilip Reames; CHECK-NEXT: entry: 222c0df6bc9SPhilip Reames; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 223c0df6bc9SPhilip Reames; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[VSCALE]], 8 224c0df6bc9SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[MUL]] 225c0df6bc9SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 226c0df6bc9SPhilip Reames; CHECK: vector.body: 227*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 228c0df6bc9SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 229*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 230*6ab686ebSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 231c0df6bc9SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 232c0df6bc9SPhilip Reames; CHECK: exit: 233c0df6bc9SPhilip Reames; CHECK-NEXT: ret void 234c0df6bc9SPhilip Reames; 235c0df6bc9SPhilip Reamesentry: 236c0df6bc9SPhilip Reames %vscale = call i64 @llvm.vscale.i64() 237c0df6bc9SPhilip Reames %mul = mul nuw nsw i64 %vscale, 8 238c0df6bc9SPhilip Reames %urem = urem i64 %N, %mul 239c0df6bc9SPhilip Reames br label %vector.body 240c0df6bc9SPhilip Reames 241c0df6bc9SPhilip Reamesvector.body: 242c0df6bc9SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 243c0df6bc9SPhilip Reames store i64 0, ptr %p 244c0df6bc9SPhilip Reames %iv.next = add i64 %iv, 2 245c0df6bc9SPhilip Reames %done = icmp eq i64 %iv.next, %urem 246c0df6bc9SPhilip Reames br i1 %done, label %exit, label %vector.body 247c0df6bc9SPhilip Reames 248c0df6bc9SPhilip Reamesexit: 249c0df6bc9SPhilip Reames ret void 250c0df6bc9SPhilip Reames} 251c0df6bc9SPhilip Reames 252c0df6bc9SPhilip Reames 253c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_mul64(i64 %N, ptr %p) { 254c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_mul64( 255c0df6bc9SPhilip Reames; CHECK-NEXT: entry: 256c0df6bc9SPhilip Reames; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 257c0df6bc9SPhilip Reames; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[VSCALE]], 64 258c0df6bc9SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[MUL]] 259c0df6bc9SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 260c0df6bc9SPhilip Reames; CHECK: vector.body: 261*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 262c0df6bc9SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 263*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 264*6ab686ebSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 265c0df6bc9SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 266c0df6bc9SPhilip Reames; CHECK: exit: 267c0df6bc9SPhilip Reames; CHECK-NEXT: ret void 268c0df6bc9SPhilip Reames; 269c0df6bc9SPhilip Reamesentry: 270c0df6bc9SPhilip Reames %vscale = call i64 @llvm.vscale.i64() 271c0df6bc9SPhilip Reames %mul = mul nuw nsw i64 %vscale, 64 272c0df6bc9SPhilip Reames %urem = urem i64 %N, %mul 273c0df6bc9SPhilip Reames br label %vector.body 274c0df6bc9SPhilip Reames 275c0df6bc9SPhilip Reamesvector.body: 276c0df6bc9SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 277c0df6bc9SPhilip Reames store i64 0, ptr %p 278c0df6bc9SPhilip Reames %iv.next = add i64 %iv, 2 279c0df6bc9SPhilip Reames %done = icmp eq i64 %iv.next, %urem 280c0df6bc9SPhilip Reames br i1 %done, label %exit, label %vector.body 281c0df6bc9SPhilip Reames 282c0df6bc9SPhilip Reamesexit: 283c0df6bc9SPhilip Reames ret void 284c0df6bc9SPhilip Reames} 285c0df6bc9SPhilip Reames 286c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_shl3(i64 %N, ptr %p) { 287c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_shl3( 288c0df6bc9SPhilip Reames; CHECK-NEXT: entry: 289c0df6bc9SPhilip Reames; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 290c0df6bc9SPhilip Reames; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[VSCALE]], 3 291c0df6bc9SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[SHL]] 292c0df6bc9SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 293c0df6bc9SPhilip Reames; CHECK: vector.body: 294*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 295c0df6bc9SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 296*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 297*6ab686ebSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 298c0df6bc9SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 299c0df6bc9SPhilip Reames; CHECK: exit: 300c0df6bc9SPhilip Reames; CHECK-NEXT: ret void 301c0df6bc9SPhilip Reames; 302c0df6bc9SPhilip Reamesentry: 303c0df6bc9SPhilip Reames %vscale = call i64 @llvm.vscale.i64() 304c0df6bc9SPhilip Reames %shl = shl i64 %vscale, 3 305c0df6bc9SPhilip Reames %urem = urem i64 %N, %shl 306c0df6bc9SPhilip Reames br label %vector.body 307c0df6bc9SPhilip Reames 308c0df6bc9SPhilip Reamesvector.body: 309c0df6bc9SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 310c0df6bc9SPhilip Reames store i64 0, ptr %p 311c0df6bc9SPhilip Reames %iv.next = add i64 %iv, 2 312c0df6bc9SPhilip Reames %done = icmp eq i64 %iv.next, %urem 313c0df6bc9SPhilip Reames br i1 %done, label %exit, label %vector.body 314c0df6bc9SPhilip Reames 315c0df6bc9SPhilip Reamesexit: 316c0df6bc9SPhilip Reames ret void 317c0df6bc9SPhilip Reames} 318c0df6bc9SPhilip Reames 319c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_shl6(i64 %N, ptr %p) { 320c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_shl6( 321c0df6bc9SPhilip Reames; CHECK-NEXT: entry: 322c0df6bc9SPhilip Reames; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 323c0df6bc9SPhilip Reames; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[VSCALE]], 6 324c0df6bc9SPhilip Reames; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[N:%.*]], [[SHL]] 325c0df6bc9SPhilip Reames; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 326c0df6bc9SPhilip Reames; CHECK: vector.body: 327*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ] 328c0df6bc9SPhilip Reames; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8 329*6ab686ebSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2 330*6ab686ebSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0 331c0df6bc9SPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]] 332c0df6bc9SPhilip Reames; CHECK: exit: 333c0df6bc9SPhilip Reames; CHECK-NEXT: ret void 334c0df6bc9SPhilip Reames; 335c0df6bc9SPhilip Reamesentry: 336c0df6bc9SPhilip Reames %vscale = call i64 @llvm.vscale.i64() 337c0df6bc9SPhilip Reames %shl = shl i64 %vscale, 6 338c0df6bc9SPhilip Reames %urem = urem i64 %N, %shl 339c0df6bc9SPhilip Reames br label %vector.body 340c0df6bc9SPhilip Reames 341c0df6bc9SPhilip Reamesvector.body: 342c0df6bc9SPhilip Reames %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ] 343c0df6bc9SPhilip Reames store i64 0, ptr %p 344c0df6bc9SPhilip Reames %iv.next = add i64 %iv, 2 345c0df6bc9SPhilip Reames %done = icmp eq i64 %iv.next, %urem 346c0df6bc9SPhilip Reames br i1 %done, label %exit, label %vector.body 347c0df6bc9SPhilip Reames 348c0df6bc9SPhilip Reamesexit: 349c0df6bc9SPhilip Reames ret void 350c0df6bc9SPhilip Reames} 351c0df6bc9SPhilip Reames 3522aed3cdbSPhilip Reames; Loop invariant does not neccessarily mean dominating the loop. Forming 3532aed3cdbSPhilip Reames; an ICmpZero from this example would be illegal even though the operands 3542aed3cdbSPhilip Reames; to the compare are loop invariant. 3552aed3cdbSPhilip Reamesdefine void @loop_invariant_definition(i64 %arg) { 3562aed3cdbSPhilip Reames; CHECK-LABEL: @loop_invariant_definition( 3572aed3cdbSPhilip Reames; CHECK-NEXT: entry: 3582aed3cdbSPhilip Reames; CHECK-NEXT: br label [[T1:%.*]] 3592aed3cdbSPhilip Reames; CHECK: t1: 3602aed3cdbSPhilip Reames; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[T1]] ], [ -1, [[ENTRY:%.*]] ] 3612aed3cdbSPhilip Reames; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], 1 3622aed3cdbSPhilip Reames; CHECK-NEXT: br i1 true, label [[T4:%.*]], label [[T1]] 3632aed3cdbSPhilip Reames; CHECK: t4: 3642aed3cdbSPhilip Reames; CHECK-NEXT: [[T5:%.*]] = trunc i64 [[LSR_IV_NEXT]] to i32 3652aed3cdbSPhilip Reames; CHECK-NEXT: [[T6:%.*]] = add i32 [[T5]], 1 3662aed3cdbSPhilip Reames; CHECK-NEXT: [[T7:%.*]] = icmp eq i32 [[T5]], [[T6]] 3672aed3cdbSPhilip Reames; CHECK-NEXT: ret void 3682aed3cdbSPhilip Reames; 3692aed3cdbSPhilip Reamesentry: 3702aed3cdbSPhilip Reames br label %t1 3712aed3cdbSPhilip Reames 3722aed3cdbSPhilip Reamest1: ; preds = %1, %0 3732aed3cdbSPhilip Reames %t2 = phi i64 [ %t3, %t1 ], [ 0, %entry ] 3742aed3cdbSPhilip Reames %t3 = add nuw i64 %t2, 1 3752aed3cdbSPhilip Reames br i1 true, label %t4, label %t1 3762aed3cdbSPhilip Reames 3772aed3cdbSPhilip Reamest4: ; preds = %1 3782aed3cdbSPhilip Reames %t5 = trunc i64 %t2 to i32 3792aed3cdbSPhilip Reames %t6 = add i32 %t5, 1 3802aed3cdbSPhilip Reames %t7 = icmp eq i32 %t5, %t6 3812aed3cdbSPhilip Reames ret void 3822aed3cdbSPhilip Reames} 3832aed3cdbSPhilip Reames 384ddd4ed99SPhilip Reamesdeclare i64 @llvm.vscale.i64() 385