1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -passes='print<access-info>' %s -disable-output 2>&1 | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" 5 6; {0,+,3} [nssw] implies {0,+,2} [nssw] 7define void @wrap_check_iv.3_implies_iv.2(i32 noundef %N, ptr %dst, ptr %src) { 8; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2' 9; CHECK-NEXT: loop: 10; CHECK-NEXT: Memory dependences are safe with run-time checks 11; CHECK-NEXT: Dependences: 12; CHECK-NEXT: Run-time memory checks: 13; CHECK-NEXT: Check 0: 14; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]): 15; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 16; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]): 17; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 18; CHECK-NEXT: Grouped accesses: 19; CHECK-NEXT: Group [[GRP1]]: 20; CHECK-NEXT: (Low: %dst High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst)) 21; CHECK-NEXT: Member: {%dst,+,12}<%loop> 22; CHECK-NEXT: Group [[GRP2]]: 23; CHECK-NEXT: (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 24; CHECK-NEXT: Member: {%src,+,8}<%loop> 25; CHECK-EMPTY: 26; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 27; CHECK-NEXT: SCEV assumptions: 28; CHECK-NEXT: {0,+,3}<%loop> Added Flags: <nssw> 29; CHECK-EMPTY: 30; CHECK-NEXT: Expressions re-written: 31; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2: 32; CHECK-NEXT: ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src) 33; CHECK-NEXT: --> {%src,+,8}<%loop> 34; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3: 35; CHECK-NEXT: ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %dst) 36; CHECK-NEXT: --> {%dst,+,12}<%loop> 37; 38entry: 39 br label %loop 40 41loop: 42 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 43 %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ] 44 %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ] 45 %ext.iv.2 = sext i32 %iv.2 to i64 46 %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 47 %l = load i32, ptr %gep.iv.2, align 4 48 %ext.iv.3 = sext i32 %iv.3 to i64 49 %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 50 store i32 %l, ptr %gep.iv.3, align 4 51 %iv.1.next = add nuw nsw i32 %iv.1, 1 52 %iv.2.next = add i32 %iv.2, 2 53 %iv.3.next = add i32 %iv.3, 3 54 %ec = icmp eq i32 %iv.1.next, %N 55 br i1 %ec, label %exit, label %loop 56 57exit: 58 ret void 59} 60 61; {2,+,2} [nssw] implies {0,+,2} [nssw]. 62define void @wrap_check_iv.3_implies_iv.2_different_start(i32 noundef %N, ptr %dst, ptr %src) { 63; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2_different_start' 64; CHECK-NEXT: loop: 65; CHECK-NEXT: Memory dependences are safe with run-time checks 66; CHECK-NEXT: Dependences: 67; CHECK-NEXT: Run-time memory checks: 68; CHECK-NEXT: Check 0: 69; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]): 70; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 71; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]): 72; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 73; CHECK-NEXT: Grouped accesses: 74; CHECK-NEXT: Group [[GRP3]]: 75; CHECK-NEXT: (Low: (12 + %dst) High: (16 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst)) 76; CHECK-NEXT: Member: {(12 + %dst),+,8}<%loop> 77; CHECK-NEXT: Group [[GRP4]]: 78; CHECK-NEXT: (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 79; CHECK-NEXT: Member: {%src,+,8}<%loop> 80; CHECK-EMPTY: 81; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 82; CHECK-NEXT: SCEV assumptions: 83; CHECK-NEXT: {2,+,2}<%loop> Added Flags: <nssw> 84; CHECK-EMPTY: 85; CHECK-NEXT: Expressions re-written: 86; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2: 87; CHECK-NEXT: ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src) 88; CHECK-NEXT: --> {%src,+,8}<%loop> 89; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3: 90; CHECK-NEXT: (4 + (4 * (sext i32 {2,+,2}<%loop> to i64))<nsw> + %dst) 91; CHECK-NEXT: --> {(12 + %dst),+,8}<%loop> 92; 93entry: 94 br label %loop 95 96loop: 97 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 98 %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ] 99 %iv.3 = phi i32 [ 3, %entry ], [ %iv.3.next, %loop ] 100 %ext.iv.2 = sext i32 %iv.2 to i64 101 %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 102 %l = load i32, ptr %gep.iv.2, align 4 103 %ext.iv.3 = sext i32 %iv.3 to i64 104 %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 105 store i32 %l, ptr %gep.iv.3, align 4 106 %iv.1.next = add nuw nsw i32 %iv.1, 1 107 %iv.2.next = add i32 %iv.2, 2 108 %iv.3.next = add i32 %iv.3, 2 109 %ec = icmp eq i32 %iv.1.next, %N 110 br i1 %ec, label %exit, label %loop 111 112exit: 113 ret void 114} 115 116; {0,+,3} [nssw] implies {0,+,2} [nssw]. 117define void @wrap_check_iv.3_implies_iv.2_predicates_added_in_different_order(i32 noundef %N, ptr %dst, ptr %src) { 118; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2_predicates_added_in_different_order' 119; CHECK-NEXT: loop: 120; CHECK-NEXT: Memory dependences are safe with run-time checks 121; CHECK-NEXT: Dependences: 122; CHECK-NEXT: Run-time memory checks: 123; CHECK-NEXT: Check 0: 124; CHECK-NEXT: Comparing group ([[GRP5:0x[0-9a-f]+]]): 125; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2 126; CHECK-NEXT: Against group ([[GRP6:0x[0-9a-f]+]]): 127; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3 128; CHECK-NEXT: Grouped accesses: 129; CHECK-NEXT: Group [[GRP5]]: 130; CHECK-NEXT: (Low: %dst High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst)) 131; CHECK-NEXT: Member: {%dst,+,8}<%loop> 132; CHECK-NEXT: Group [[GRP6]]: 133; CHECK-NEXT: (Low: %src High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 134; CHECK-NEXT: Member: {%src,+,12}<%loop> 135; CHECK-EMPTY: 136; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 137; CHECK-NEXT: SCEV assumptions: 138; CHECK-NEXT: {0,+,3}<%loop> Added Flags: <nssw> 139; CHECK-EMPTY: 140; CHECK-NEXT: Expressions re-written: 141; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3: 142; CHECK-NEXT: ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %src) 143; CHECK-NEXT: --> {%src,+,12}<%loop> 144; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2: 145; CHECK-NEXT: ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %dst) 146; CHECK-NEXT: --> {%dst,+,8}<%loop> 147; 148entry: 149 br label %loop 150 151loop: 152 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 153 %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ] 154 %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ] 155 %ext.iv.3 = sext i32 %iv.3 to i64 156 %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3 157 %l = load i32, ptr %gep.iv.3, align 4 158 %ext.iv.2 = sext i32 %iv.2 to i64 159 %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2 160 store i32 %l, ptr %gep.iv.2, align 4 161 %iv.1.next = add nuw nsw i32 %iv.1, 1 162 %iv.2.next = add i32 %iv.2, 2 163 %iv.3.next = add i32 %iv.3, 3 164 %ec = icmp eq i32 %iv.1.next, %N 165 br i1 %ec, label %exit, label %loop 166 167exit: 168 ret void 169} 170 171define void @wrap_check_iv.3_does_not_implies_iv.2_due_to_start(i32 noundef %N, ptr %dst, ptr %src) { 172; CHECK-LABEL: 'wrap_check_iv.3_does_not_implies_iv.2_due_to_start' 173; CHECK-NEXT: loop: 174; CHECK-NEXT: Memory dependences are safe with run-time checks 175; CHECK-NEXT: Dependences: 176; CHECK-NEXT: Run-time memory checks: 177; CHECK-NEXT: Check 0: 178; CHECK-NEXT: Comparing group ([[GRP7:0x[0-9a-f]+]]): 179; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 180; CHECK-NEXT: Against group ([[GRP8:0x[0-9a-f]+]]): 181; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 182; CHECK-NEXT: Grouped accesses: 183; CHECK-NEXT: Group [[GRP7]]: 184; CHECK-NEXT: (Low: %dst High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst)) 185; CHECK-NEXT: Member: {%dst,+,12}<%loop> 186; CHECK-NEXT: Group [[GRP8]]: 187; CHECK-NEXT: (Low: (40 + %src) High: (44 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 188; CHECK-NEXT: Member: {(40 + %src),+,8}<%loop> 189; CHECK-EMPTY: 190; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 191; CHECK-NEXT: SCEV assumptions: 192; CHECK-NEXT: {0,+,3}<%loop> Added Flags: <nssw> 193; CHECK-NEXT: {10,+,2}<%loop> Added Flags: <nssw> 194; CHECK-EMPTY: 195; CHECK-NEXT: Expressions re-written: 196; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2: 197; CHECK-NEXT: ((4 * (sext i32 {10,+,2}<%loop> to i64))<nsw> + %src) 198; CHECK-NEXT: --> {(40 + %src),+,8}<%loop> 199; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3: 200; CHECK-NEXT: ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %dst) 201; CHECK-NEXT: --> {%dst,+,12}<%loop> 202; 203entry: 204 br label %loop 205 206loop: 207 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 208 %iv.2 = phi i32 [ 10, %entry ], [ %iv.2.next, %loop ] 209 %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ] 210 %ext.iv.2 = sext i32 %iv.2 to i64 211 %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 212 %l = load i32, ptr %gep.iv.2, align 4 213 %ext.iv.3 = sext i32 %iv.3 to i64 214 %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 215 store i32 %l, ptr %gep.iv.3, align 4 216 %iv.1.next = add nuw nsw i32 %iv.1, 1 217 %iv.2.next = add i32 %iv.2, 2 218 %iv.3.next = add i32 %iv.3, 3 219 %ec = icmp eq i32 %iv.1.next, %N 220 br i1 %ec, label %exit, label %loop 221 222exit: 223 ret void 224} 225 226define void @wrap_check_iv.3_does_not_imply_iv.2_due_to_start_negative(i32 noundef %N, ptr %dst, ptr %src) { 227; CHECK-LABEL: 'wrap_check_iv.3_does_not_imply_iv.2_due_to_start_negative' 228; CHECK-NEXT: loop: 229; CHECK-NEXT: Memory dependences are safe with run-time checks 230; CHECK-NEXT: Dependences: 231; CHECK-NEXT: Run-time memory checks: 232; CHECK-NEXT: Check 0: 233; CHECK-NEXT: Comparing group ([[GRP9:0x[0-9a-f]+]]): 234; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 235; CHECK-NEXT: Against group ([[GRP10:0x[0-9a-f]+]]): 236; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 237; CHECK-NEXT: Grouped accesses: 238; CHECK-NEXT: Group [[GRP9]]: 239; CHECK-NEXT: (Low: (-4 + %dst) High: ((12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst)) 240; CHECK-NEXT: Member: {(-4 + %dst),+,12}<%loop> 241; CHECK-NEXT: Group [[GRP10]]: 242; CHECK-NEXT: (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 243; CHECK-NEXT: Member: {%src,+,8}<%loop> 244; CHECK-EMPTY: 245; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 246; CHECK-NEXT: SCEV assumptions: 247; CHECK-NEXT: {-1,+,3}<%loop> Added Flags: <nssw> 248; CHECK-NEXT: {0,+,2}<%loop> Added Flags: <nssw> 249; CHECK-EMPTY: 250; CHECK-NEXT: Expressions re-written: 251; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2: 252; CHECK-NEXT: ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src) 253; CHECK-NEXT: --> {%src,+,8}<%loop> 254; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3: 255; CHECK-NEXT: ((4 * (sext i32 {-1,+,3}<%loop> to i64))<nsw> + %dst) 256; CHECK-NEXT: --> {(-4 + %dst),+,12}<%loop> 257; 258entry: 259 br label %loop 260 261loop: 262 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 263 %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ] 264 %iv.3 = phi i32 [ -1, %entry ], [ %iv.3.next, %loop ] 265 %ext.iv.2 = sext i32 %iv.2 to i64 266 %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 267 %l = load i32, ptr %gep.iv.2, align 4 268 %ext.iv.3 = sext i32 %iv.3 to i64 269 %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 270 store i32 %l, ptr %gep.iv.3, align 4 271 %iv.1.next = add nuw nsw i32 %iv.1, 1 272 %iv.2.next = add i32 %iv.2, 2 273 %iv.3.next = add i32 %iv.3, 3 274 %ec = icmp eq i32 %iv.1.next, %N 275 br i1 %ec, label %exit, label %loop 276 277exit: 278 ret void 279} 280 281define void @wrap_check_iv.3_does_not_imply_iv.2_due_to_negative_step(i32 noundef %N, ptr %dst, ptr %src) { 282; CHECK-LABEL: 'wrap_check_iv.3_does_not_imply_iv.2_due_to_negative_step' 283; CHECK-NEXT: loop: 284; CHECK-NEXT: Memory dependences are safe with run-time checks 285; CHECK-NEXT: Dependences: 286; CHECK-NEXT: Run-time memory checks: 287; CHECK-NEXT: Check 0: 288; CHECK-NEXT: Comparing group ([[GRP11:0x[0-9a-f]+]]): 289; CHECK-NEXT: %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 290; CHECK-NEXT: Against group ([[GRP12:0x[0-9a-f]+]]): 291; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 292; CHECK-NEXT: Grouped accesses: 293; CHECK-NEXT: Group [[GRP11]]: 294; CHECK-NEXT: (Low: ((-4 * (zext i32 (-1 + %N) to i64))<nsw> + %dst) High: (4 + %dst)) 295; CHECK-NEXT: Member: {%dst,+,-4}<%loop> 296; CHECK-NEXT: Group [[GRP12]]: 297; CHECK-NEXT: (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src)) 298; CHECK-NEXT: Member: {%src,+,8}<%loop> 299; CHECK-EMPTY: 300; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 301; CHECK-NEXT: SCEV assumptions: 302; CHECK-NEXT: {0,+,-1}<%loop> Added Flags: <nssw> 303; CHECK-NEXT: {0,+,2}<%loop> Added Flags: <nssw> 304; CHECK-EMPTY: 305; CHECK-NEXT: Expressions re-written: 306; CHECK-NEXT: [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2: 307; CHECK-NEXT: ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src) 308; CHECK-NEXT: --> {%src,+,8}<%loop> 309; CHECK-NEXT: [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3: 310; CHECK-NEXT: ((4 * (sext i32 {0,+,-1}<%loop> to i64))<nsw> + %dst) 311; CHECK-NEXT: --> {%dst,+,-4}<%loop> 312; 313entry: 314 br label %loop 315 316loop: 317 %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ] 318 %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ] 319 %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ] 320 %ext.iv.2 = sext i32 %iv.2 to i64 321 %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2 322 %l = load i32, ptr %gep.iv.2, align 4 323 %ext.iv.3 = sext i32 %iv.3 to i64 324 %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3 325 store i32 %l, ptr %gep.iv.3, align 4 326 %iv.1.next = add nuw nsw i32 %iv.1, 1 327 %iv.2.next = add i32 %iv.2, 2 328 %iv.3.next = add i32 %iv.3, -1 329 %ec = icmp eq i32 %iv.1.next, %N 330 br i1 %ec, label %exit, label %loop 331 332exit: 333 ret void 334} 335