1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py 2; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s 3 4define ptr @pointer_align_down(ptr %obj) { 5; CHECK-LABEL: 'pointer_align_down' 6; CHECK-NEXT: Classifying expressions for: @pointer_align_down 7; CHECK-NEXT: %i = ptrtoint ptr %obj to i64 8; CHECK-NEXT: --> (ptrtoint ptr %obj to i64) U: full-set S: full-set 9; CHECK-NEXT: %i2 = and i64 %i, 15 10; CHECK-NEXT: --> (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64) U: [0,16) S: [0,16) 11; CHECK-NEXT: %i3 = sub nsw i64 0, %i2 12; CHECK-NEXT: --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1) 13; CHECK-NEXT: %i4 = getelementptr i8, ptr %obj, i64 %i3 14; CHECK-NEXT: --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set 15; CHECK-NEXT: Determining loop execution counts for: @pointer_align_down 16; 17 %i = ptrtoint ptr %obj to i64 18 %i2 = and i64 %i, 15 19 %i3 = sub nsw i64 0, %i2 20 %i4 = getelementptr i8, ptr %obj, i64 %i3 21 ret ptr %i4 22} 23 24define ptr @pointer_align_down_different_donor(ptr %obj_to_align, ptr %obj_donor) { 25; CHECK-LABEL: 'pointer_align_down_different_donor' 26; CHECK-NEXT: Classifying expressions for: @pointer_align_down_different_donor 27; CHECK-NEXT: %i = ptrtoint ptr %obj_donor to i64 28; CHECK-NEXT: --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set 29; CHECK-NEXT: %i2 = and i64 %i, 15 30; CHECK-NEXT: --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16) 31; CHECK-NEXT: %i3 = sub nsw i64 0, %i2 32; CHECK-NEXT: --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1) 33; CHECK-NEXT: %i4 = getelementptr i8, ptr %obj_to_align, i64 %i3 34; CHECK-NEXT: --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set 35; CHECK-NEXT: Determining loop execution counts for: @pointer_align_down_different_donor 36; 37 %i = ptrtoint ptr %obj_donor to i64 38 %i2 = and i64 %i, 15 39 %i3 = sub nsw i64 0, %i2 40 %i4 = getelementptr i8, ptr %obj_to_align, i64 %i3 41 ret ptr %i4 42} 43 44define ptr @pointer_align_up(ptr noundef %obj) { 45; CHECK-LABEL: 'pointer_align_up' 46; CHECK-NEXT: Classifying expressions for: @pointer_align_up 47; CHECK-NEXT: %intptr = ptrtoint ptr %obj to i64 48; CHECK-NEXT: --> (ptrtoint ptr %obj to i64) U: full-set S: full-set 49; CHECK-NEXT: %over_boundary = add i64 %intptr, 15 50; CHECK-NEXT: --> (15 + (ptrtoint ptr %obj to i64)) U: full-set S: full-set 51; CHECK-NEXT: %aligned_intptr = and i64 %over_boundary, -16 52; CHECK-NEXT: --> (16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> U: [0,-15) S: [-9223372036854775808,9223372036854775793) 53; CHECK-NEXT: %diff = sub i64 %aligned_intptr, %intptr 54; CHECK-NEXT: --> ((16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj to i64))) U: full-set S: full-set 55; CHECK-NEXT: %aligned_result = getelementptr i8, ptr %obj, i64 %diff 56; CHECK-NEXT: --> ((16 * ((15 + (ptrtoint ptr %obj to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj to i64)) + %obj) U: full-set S: full-set 57; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up 58; 59 %intptr = ptrtoint ptr %obj to i64 60 %over_boundary = add i64 %intptr, 15 61 %aligned_intptr = and i64 %over_boundary, -16 62 %diff = sub i64 %aligned_intptr, %intptr 63 %aligned_result = getelementptr i8, ptr %obj, i64 %diff 64 ret ptr %aligned_result 65} 66 67define ptr @pointer_align_up_different_donor(ptr noundef %obj_to_align, ptr %obj_donor) { 68; CHECK-LABEL: 'pointer_align_up_different_donor' 69; CHECK-NEXT: Classifying expressions for: @pointer_align_up_different_donor 70; CHECK-NEXT: %intptr = ptrtoint ptr %obj_donor to i64 71; CHECK-NEXT: --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set 72; CHECK-NEXT: %over_boundary = add i64 %intptr, 15 73; CHECK-NEXT: --> (15 + (ptrtoint ptr %obj_donor to i64)) U: full-set S: full-set 74; CHECK-NEXT: %aligned_intptr = and i64 %over_boundary, -16 75; CHECK-NEXT: --> (16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> U: [0,-15) S: [-9223372036854775808,9223372036854775793) 76; CHECK-NEXT: %diff = sub i64 %aligned_intptr, %intptr 77; CHECK-NEXT: --> ((16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj_donor to i64))) U: full-set S: full-set 78; CHECK-NEXT: %aligned_result = getelementptr i8, ptr %obj_to_align, i64 %diff 79; CHECK-NEXT: --> ((16 * ((15 + (ptrtoint ptr %obj_donor to i64)) /u 16))<nuw> + (-1 * (ptrtoint ptr %obj_donor to i64)) + %obj_to_align) U: full-set S: full-set 80; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_different_donor 81; 82 %intptr = ptrtoint ptr %obj_donor to i64 83 %over_boundary = add i64 %intptr, 15 84 %aligned_intptr = and i64 %over_boundary, -16 85 %diff = sub i64 %aligned_intptr, %intptr 86 %aligned_result = getelementptr i8, ptr %obj_to_align, i64 %diff 87 ret ptr %aligned_result 88} 89 90define ptr @pointer_align_up_with_select(ptr %obj) { 91; CHECK-LABEL: 'pointer_align_up_with_select' 92; CHECK-NEXT: Classifying expressions for: @pointer_align_up_with_select 93; CHECK-NEXT: %i = ptrtoint ptr %obj to i64 94; CHECK-NEXT: --> (ptrtoint ptr %obj to i64) U: full-set S: full-set 95; CHECK-NEXT: %i2 = and i64 %i, 15 96; CHECK-NEXT: --> (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64) U: [0,16) S: [0,16) 97; CHECK-NEXT: %i4 = sub nsw i64 0, %i2 98; CHECK-NEXT: --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1) 99; CHECK-NEXT: %i5 = getelementptr i8, ptr %obj, i64 %i4 100; CHECK-NEXT: --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set 101; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 102; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64))<nsw> + %obj) U: full-set S: full-set 103; CHECK-NEXT: %i7 = select i1 %i3, ptr %obj, ptr %i6 104; CHECK-NEXT: --> %i7 U: full-set S: full-set 105; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select 106; 107 %i = ptrtoint ptr %obj to i64 108 %i2 = and i64 %i, 15 109 %i3 = icmp eq i64 %i2, 0 110 %i4 = sub nsw i64 0, %i2 111 %i5 = getelementptr i8, ptr %obj, i64 %i4 112 %i6 = getelementptr i8, ptr %i5, i64 16 113 %i7 = select i1 %i3, ptr %obj, ptr %i6 114 ret ptr %i7 115} 116 117define ptr @pointer_align_up_with_select_different_donor(ptr %obj_to_align, ptr %obj_donor) { 118; CHECK-LABEL: 'pointer_align_up_with_select_different_donor' 119; CHECK-NEXT: Classifying expressions for: @pointer_align_up_with_select_different_donor 120; CHECK-NEXT: %i = ptrtoint ptr %obj_donor to i64 121; CHECK-NEXT: --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set 122; CHECK-NEXT: %i2 = and i64 %i, 15 123; CHECK-NEXT: --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16) 124; CHECK-NEXT: %i4 = sub nsw i64 0, %i2 125; CHECK-NEXT: --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1) 126; CHECK-NEXT: %i5 = getelementptr i8, ptr %obj_to_align, i64 %i4 127; CHECK-NEXT: --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set 128; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 129; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %obj_to_align) U: full-set S: full-set 130; CHECK-NEXT: %i7 = select i1 %i3, ptr %obj_to_align, ptr %i6 131; CHECK-NEXT: --> %i7 U: full-set S: full-set 132; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select_different_donor 133; 134 %i = ptrtoint ptr %obj_donor to i64 135 %i2 = and i64 %i, 15 136 %i3 = icmp eq i64 %i2, 0 137 %i4 = sub nsw i64 0, %i2 138 %i5 = getelementptr i8, ptr %obj_to_align, i64 %i4 139 %i6 = getelementptr i8, ptr %i5, i64 16 140 %i7 = select i1 %i3, ptr %obj_to_align, ptr %i6 141 ret ptr %i7 142} 143 144define ptr @pointer_align_up_with_select_different_objects_bad(ptr %first_obj, ptr %second_obj, ptr %obj_donor) { 145; CHECK-LABEL: 'pointer_align_up_with_select_different_objects_bad' 146; CHECK-NEXT: Classifying expressions for: @pointer_align_up_with_select_different_objects_bad 147; CHECK-NEXT: %i = ptrtoint ptr %obj_donor to i64 148; CHECK-NEXT: --> (ptrtoint ptr %obj_donor to i64) U: full-set S: full-set 149; CHECK-NEXT: %i2 = and i64 %i, 15 150; CHECK-NEXT: --> (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64) U: [0,16) S: [0,16) 151; CHECK-NEXT: %i4 = sub nsw i64 0, %i2 152; CHECK-NEXT: --> (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> U: [-15,1) S: [-15,1) 153; CHECK-NEXT: %i5 = getelementptr i8, ptr %second_obj, i64 %i4 154; CHECK-NEXT: --> ((-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %second_obj) U: full-set S: full-set 155; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 156; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64))<nsw> + %second_obj) U: full-set S: full-set 157; CHECK-NEXT: %i7 = select i1 %i3, ptr %first_obj, ptr %i6 158; CHECK-NEXT: --> %i7 U: full-set S: full-set 159; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select_different_objects_bad 160; 161 %i = ptrtoint ptr %obj_donor to i64 162 %i2 = and i64 %i, 15 163 %i3 = icmp eq i64 %i2, 0 164 %i4 = sub nsw i64 0, %i2 165 %i5 = getelementptr i8, ptr %second_obj, i64 %i4 166 %i6 = getelementptr i8, ptr %i5, i64 16 167 %i7 = select i1 %i3, ptr %first_obj, ptr %i6 168 ret ptr %i7 169} 170