1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck --check-prefixes=COMMON,MAXLEN %s 3; RUN: opt -passes='print<access-info>' -disable-output -mtriple=arm64-apple-macosx %s 2>&1 | FileCheck --check-prefixes=COMMON,VW128 %s 4; RUN: opt -passes='print<access-info>' -disable-output -mtriple=arm64-apple-macosx -mattr=+sve %s 2>&1 | FileCheck --check-prefixes=COMMON,MAXLEN %s 5 6; REQUIRES: aarch64-registered-target 7 8target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 9 10; If the dependence distance is not a constant, whether it gets identified as backwards or unknown depends on the minimum distance and the target's vector length. 11 12define void @backward_min_distance_8(ptr %A, i64 %N) { 13; COMMON-LABEL: 'backward_min_distance_8' 14; COMMON-NEXT: loop: 15; COMMON-NEXT: Memory dependences are safe with run-time checks 16; COMMON-NEXT: Dependences: 17; COMMON-NEXT: Run-time memory checks: 18; COMMON-NEXT: Check 0: 19; COMMON-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]): 20; COMMON-NEXT: %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 21; COMMON-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]): 22; COMMON-NEXT: %gep = getelementptr inbounds i8, ptr %A, i64 %iv 23; COMMON-NEXT: Grouped accesses: 24; COMMON-NEXT: Group [[GRP1]]: 25; COMMON-NEXT: (Low: {(1 + %A)<nuw>,+,1}<nuw><%outer.header> High: {(257 + %A),+,1}<nw><%outer.header>) 26; COMMON-NEXT: Member: {{\{\{}}(1 + %A)<nuw>,+,1}<nuw><%outer.header>,+,1}<nuw><%loop> 27; COMMON-NEXT: Group [[GRP2]]: 28; COMMON-NEXT: (Low: %A High: (256 + %A)) 29; COMMON-NEXT: Member: {%A,+,1}<nuw><%loop> 30; COMMON-EMPTY: 31; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 32; COMMON-NEXT: SCEV assumptions: 33; COMMON-EMPTY: 34; COMMON-NEXT: Expressions re-written: 35; COMMON-NEXT: outer.header: 36; COMMON-NEXT: Report: loop is not the innermost loop 37; COMMON-NEXT: Dependences: 38; COMMON-NEXT: Run-time memory checks: 39; COMMON-NEXT: Grouped accesses: 40; COMMON-EMPTY: 41; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 42; COMMON-NEXT: SCEV assumptions: 43; COMMON-EMPTY: 44; COMMON-NEXT: Expressions re-written: 45; 46entry: 47 br label %outer.header 48 49outer.header: 50 %outer.iv = phi i64 [ 1, %entry ], [ %outer.iv.next, %outer.latch ] 51 %gep.off = getelementptr inbounds i8, ptr %A, i64 %outer.iv 52 br label %loop 53 54loop: 55 %iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop ] 56 %gep = getelementptr inbounds i8, ptr %A, i64 %iv 57 %l = load i8 , ptr %gep, align 4 58 %add = add nsw i8 %l, 5 59 %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 60 store i8 %add, ptr %gep.off.iv, align 4 61 %iv.next = add nuw nsw i64 %iv, 1 62 %exitcond.not = icmp eq i64 %iv.next, 256 63 br i1 %exitcond.not, label %outer.latch, label %loop 64 65outer.latch: 66 %outer.iv.next = add nuw nsw i64 %outer.iv, 1 67 %ec.2 = icmp eq i64 %outer.iv.next, %N 68 br i1 %ec.2, label %exit, label %outer.header 69 70exit: 71 ret void 72} 73 74define void @backward_min_distance_120(ptr %A, i64 %N) { 75; COMMON-LABEL: 'backward_min_distance_120' 76; COMMON-NEXT: loop: 77; COMMON-NEXT: Memory dependences are safe with run-time checks 78; COMMON-NEXT: Dependences: 79; COMMON-NEXT: Run-time memory checks: 80; COMMON-NEXT: Check 0: 81; COMMON-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]): 82; COMMON-NEXT: %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 83; COMMON-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]): 84; COMMON-NEXT: %gep = getelementptr inbounds i8, ptr %A, i64 %iv 85; COMMON-NEXT: Grouped accesses: 86; COMMON-NEXT: Group [[GRP3]]: 87; COMMON-NEXT: (Low: {(15 + %A)<nuw>,+,1}<nuw><%outer.header> High: {(271 + %A),+,1}<nw><%outer.header>) 88; COMMON-NEXT: Member: {{\{\{}}(15 + %A)<nuw>,+,1}<nuw><%outer.header>,+,1}<nuw><%loop> 89; COMMON-NEXT: Group [[GRP4]]: 90; COMMON-NEXT: (Low: %A High: (256 + %A)) 91; COMMON-NEXT: Member: {%A,+,1}<nuw><%loop> 92; COMMON-EMPTY: 93; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 94; COMMON-NEXT: SCEV assumptions: 95; COMMON-EMPTY: 96; COMMON-NEXT: Expressions re-written: 97; COMMON-NEXT: outer.header: 98; COMMON-NEXT: Report: loop is not the innermost loop 99; COMMON-NEXT: Dependences: 100; COMMON-NEXT: Run-time memory checks: 101; COMMON-NEXT: Grouped accesses: 102; COMMON-EMPTY: 103; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 104; COMMON-NEXT: SCEV assumptions: 105; COMMON-EMPTY: 106; COMMON-NEXT: Expressions re-written: 107; 108entry: 109 br label %outer.header 110 111outer.header: 112 %outer.iv = phi i64 [ 15, %entry ], [ %outer.iv.next, %outer.latch ] 113 %gep.off = getelementptr inbounds i8, ptr %A, i64 %outer.iv 114 br label %loop 115 116loop: 117 %iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop ] 118 %gep = getelementptr inbounds i8, ptr %A, i64 %iv 119 %l = load i8 , ptr %gep, align 4 120 %add = add nsw i8 %l, 5 121 %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 122 store i8 %add, ptr %gep.off.iv, align 4 123 %iv.next = add nuw nsw i64 %iv, 1 124 %exitcond.not = icmp eq i64 %iv.next, 256 125 br i1 %exitcond.not, label %outer.latch, label %loop 126 127outer.latch: 128 %outer.iv.next = add nuw nsw i64 %outer.iv, 1 129 %ec.2 = icmp eq i64 %outer.iv.next, %N 130 br i1 %ec.2, label %exit, label %outer.header 131 132exit: 133 ret void 134} 135 136define void @backward_min_distance_128(ptr %A, i64 %N) { 137; COMMON-LABEL: 'backward_min_distance_128' 138; COMMON-NEXT: loop: 139; COMMON-NEXT: Memory dependences are safe with run-time checks 140; COMMON-NEXT: Dependences: 141; COMMON-NEXT: Run-time memory checks: 142; COMMON-NEXT: Check 0: 143; COMMON-NEXT: Comparing group ([[GRP13:0x[0-9a-f]+]]): 144; COMMON-NEXT: %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 145; COMMON-NEXT: Against group ([[GRP14:0x[0-9a-f]+]]): 146; COMMON-NEXT: %gep = getelementptr inbounds i8, ptr %A, i64 %iv 147; COMMON-NEXT: Grouped accesses: 148; COMMON-NEXT: Group [[GRP13]]: 149; COMMON-NEXT: (Low: {(16 + %A)<nuw>,+,1}<nuw><%outer.header> High: {(272 + %A),+,1}<nw><%outer.header>) 150; COMMON-NEXT: Member: {{\{\{}}(16 + %A)<nuw>,+,1}<nuw><%outer.header>,+,1}<nuw><%loop> 151; COMMON-NEXT: Group [[GRP14]]: 152; COMMON-NEXT: (Low: %A High: (256 + %A)) 153; COMMON-NEXT: Member: {%A,+,1}<nuw><%loop> 154; COMMON-EMPTY: 155; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 156; COMMON-NEXT: SCEV assumptions: 157; COMMON-EMPTY: 158; COMMON-NEXT: Expressions re-written: 159; COMMON-NEXT: outer.header: 160; COMMON-NEXT: Report: loop is not the innermost loop 161; COMMON-NEXT: Dependences: 162; COMMON-NEXT: Run-time memory checks: 163; COMMON-NEXT: Grouped accesses: 164; COMMON-EMPTY: 165; COMMON-NEXT: Non vectorizable stores to invariant address were not found in loop. 166; COMMON-NEXT: SCEV assumptions: 167; COMMON-EMPTY: 168; COMMON-NEXT: Expressions re-written: 169; 170entry: 171 br label %outer.header 172 173outer.header: 174 %outer.iv = phi i64 [ 16, %entry ], [ %outer.iv.next, %outer.latch ] 175 %gep.off = getelementptr inbounds i8, ptr %A, i64 %outer.iv 176 br label %loop 177 178loop: 179 %iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop ] 180 %gep = getelementptr inbounds i8, ptr %A, i64 %iv 181 %l = load i8 , ptr %gep, align 4 182 %add = add nsw i8 %l, 5 183 %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 184 store i8 %add, ptr %gep.off.iv, align 4 185 %iv.next = add nuw nsw i64 %iv, 1 186 %exitcond.not = icmp eq i64 %iv.next, 256 187 br i1 %exitcond.not, label %outer.latch, label %loop 188 189outer.latch: 190 %outer.iv.next = add nuw nsw i64 %outer.iv, 1 191 %ec.2 = icmp eq i64 %outer.iv.next, %N 192 br i1 %ec.2, label %exit, label %outer.header 193 194exit: 195 ret void 196} 197 198define void @backward_min_distance_256(ptr %A, i64 %N) { 199; MAXLEN-LABEL: 'backward_min_distance_256' 200; MAXLEN-NEXT: loop: 201; MAXLEN-NEXT: Memory dependences are safe with run-time checks 202; MAXLEN-NEXT: Dependences: 203; MAXLEN-NEXT: Run-time memory checks: 204; MAXLEN-NEXT: Check 0: 205; MAXLEN-NEXT: Comparing group ([[GRP17:0x[0-9a-f]+]]): 206; MAXLEN-NEXT: %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 207; MAXLEN-NEXT: Against group ([[GRP18:0x[0-9a-f]+]]): 208; MAXLEN-NEXT: %gep = getelementptr inbounds i8, ptr %A, i64 %iv 209; MAXLEN-NEXT: Grouped accesses: 210; MAXLEN-NEXT: Group [[GRP17]]: 211; MAXLEN-NEXT: (Low: {(32 + %A)<nuw>,+,1}<nuw><%outer.header> High: {(288 + %A),+,1}<nw><%outer.header>) 212; MAXLEN-NEXT: Member: {{\{\{}}(32 + %A)<nuw>,+,1}<nuw><%outer.header>,+,1}<nuw><%loop> 213; MAXLEN-NEXT: Group [[GRP18]]: 214; MAXLEN-NEXT: (Low: %A High: (256 + %A)) 215; MAXLEN-NEXT: Member: {%A,+,1}<nuw><%loop> 216; MAXLEN-EMPTY: 217; MAXLEN-NEXT: Non vectorizable stores to invariant address were not found in loop. 218; MAXLEN-NEXT: SCEV assumptions: 219; MAXLEN-EMPTY: 220; MAXLEN-NEXT: Expressions re-written: 221; MAXLEN-NEXT: outer.header: 222; MAXLEN-NEXT: Report: loop is not the innermost loop 223; MAXLEN-NEXT: Dependences: 224; MAXLEN-NEXT: Run-time memory checks: 225; MAXLEN-NEXT: Grouped accesses: 226; MAXLEN-EMPTY: 227; MAXLEN-NEXT: Non vectorizable stores to invariant address were not found in loop. 228; MAXLEN-NEXT: SCEV assumptions: 229; MAXLEN-EMPTY: 230; MAXLEN-NEXT: Expressions re-written: 231; 232; VW128-LABEL: 'backward_min_distance_256' 233; VW128-NEXT: loop: 234; VW128-NEXT: Memory dependences are safe with a maximum safe vector width of 256 bits 235; VW128-NEXT: Dependences: 236; VW128-NEXT: BackwardVectorizable: 237; VW128-NEXT: %l = load i8, ptr %gep, align 4 -> 238; VW128-NEXT: store i8 %add, ptr %gep.off.iv, align 4 239; VW128-EMPTY: 240; VW128-NEXT: Run-time memory checks: 241; VW128-NEXT: Grouped accesses: 242; VW128-EMPTY: 243; VW128-NEXT: Non vectorizable stores to invariant address were not found in loop. 244; VW128-NEXT: SCEV assumptions: 245; VW128-EMPTY: 246; VW128-NEXT: Expressions re-written: 247; VW128-NEXT: outer.header: 248; VW128-NEXT: Report: loop is not the innermost loop 249; VW128-NEXT: Dependences: 250; VW128-NEXT: Run-time memory checks: 251; VW128-NEXT: Grouped accesses: 252; VW128-EMPTY: 253; VW128-NEXT: Non vectorizable stores to invariant address were not found in loop. 254; VW128-NEXT: SCEV assumptions: 255; VW128-EMPTY: 256; VW128-NEXT: Expressions re-written: 257; 258entry: 259 br label %outer.header 260 261outer.header: 262 %outer.iv = phi i64 [ 32, %entry ], [ %outer.iv.next, %outer.latch ] 263 %gep.off = getelementptr inbounds i8, ptr %A, i64 %outer.iv 264 br label %loop 265 266loop: 267 %iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop ] 268 %gep = getelementptr inbounds i8, ptr %A, i64 %iv 269 %l = load i8 , ptr %gep, align 4 270 %add = add nsw i8 %l, 5 271 %gep.off.iv = getelementptr inbounds i8, ptr %gep.off, i64 %iv 272 store i8 %add, ptr %gep.off.iv, align 4 273 %iv.next = add nuw nsw i64 %iv, 1 274 %exitcond.not = icmp eq i64 %iv.next, 256 275 br i1 %exitcond.not, label %outer.latch, label %loop 276 277outer.latch: 278 %outer.iv.next = add nuw nsw i64 %outer.iv, 1 279 %ec.2 = icmp eq i64 %outer.iv.next, %N 280 br i1 %ec.2, label %exit, label %outer.header 281 282exit: 283 ret void 284} 285