1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py 2; RUN: opt < %s --data-layout="e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -S -analyze -enable-new-pm=0 -scalar-evolution | FileCheck --check-prefixes=ALL,X64 %s 3; RUN: opt < %s --data-layout="e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck --check-prefixes=ALL,X64 %s 4; RUN: opt < %s --data-layout="e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" -S -analyze -enable-new-pm=0 -scalar-evolution | FileCheck --check-prefixes=ALL,X32 %s 5; RUN: opt < %s --data-layout="e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck --check-prefixes=ALL,X32 %s 6 7; While we can't treat inttoptr/ptrtoint casts as fully transparent, 8; for ptrtoint cast, instead of modelling it as fully opaque (unknown), 9; we can at least model it as zext/trunc/self of an unknown, 10; iff it it's argument would be modelled as unknown anyways. 11 12declare void @useptr(i8*) 13 14; Simple ptrtoint of an argument, with casts to potentially different bit widths. 15define void @ptrtoint(i8* %in, i64* %out0, i32* %out1, i16* %out2, i128* %out3) { 16; X64-LABEL: 'ptrtoint' 17; X64-NEXT: Classifying expressions for: @ptrtoint 18; X64-NEXT: %p0 = ptrtoint i8* %in to i64 19; X64-NEXT: --> (ptrtoint i8* %in to i64) U: full-set S: full-set 20; X64-NEXT: %p1 = ptrtoint i8* %in to i32 21; X64-NEXT: --> (trunc i64 (ptrtoint i8* %in to i64) to i32) U: full-set S: full-set 22; X64-NEXT: %p2 = ptrtoint i8* %in to i16 23; X64-NEXT: --> (trunc i64 (ptrtoint i8* %in to i64) to i16) U: full-set S: full-set 24; X64-NEXT: %p3 = ptrtoint i8* %in to i128 25; X64-NEXT: --> (zext i64 (ptrtoint i8* %in to i64) to i128) U: [0,18446744073709551616) S: [0,18446744073709551616) 26; X64-NEXT: Determining loop execution counts for: @ptrtoint 27; 28; X32-LABEL: 'ptrtoint' 29; X32-NEXT: Classifying expressions for: @ptrtoint 30; X32-NEXT: %p0 = ptrtoint i8* %in to i64 31; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) 32; X32-NEXT: %p1 = ptrtoint i8* %in to i32 33; X32-NEXT: --> (ptrtoint i8* %in to i32) U: full-set S: full-set 34; X32-NEXT: %p2 = ptrtoint i8* %in to i16 35; X32-NEXT: --> (trunc i32 (ptrtoint i8* %in to i32) to i16) U: full-set S: full-set 36; X32-NEXT: %p3 = ptrtoint i8* %in to i128 37; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i128) U: [0,4294967296) S: [0,4294967296) 38; X32-NEXT: Determining loop execution counts for: @ptrtoint 39; 40 %p0 = ptrtoint i8* %in to i64 41 %p1 = ptrtoint i8* %in to i32 42 %p2 = ptrtoint i8* %in to i16 43 %p3 = ptrtoint i8* %in to i128 44 store i64 %p0, i64* %out0 45 store i32 %p1, i32* %out1 46 store i16 %p2, i16* %out2 47 store i128 %p3, i128* %out3 48 ret void 49} 50 51; Same, but from non-zero/non-default address space. 52define void @ptrtoint_as1(i8 addrspace(1)* %in, i64* %out0, i32* %out1, i16* %out2, i128* %out3) { 53; X64-LABEL: 'ptrtoint_as1' 54; X64-NEXT: Classifying expressions for: @ptrtoint_as1 55; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64 56; X64-NEXT: --> (ptrtoint i8 addrspace(1)* %in to i64) U: full-set S: full-set 57; X64-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32 58; X64-NEXT: --> (trunc i64 (ptrtoint i8 addrspace(1)* %in to i64) to i32) U: full-set S: full-set 59; X64-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16 60; X64-NEXT: --> (trunc i64 (ptrtoint i8 addrspace(1)* %in to i64) to i16) U: full-set S: full-set 61; X64-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128 62; X64-NEXT: --> (zext i64 (ptrtoint i8 addrspace(1)* %in to i64) to i128) U: [0,18446744073709551616) S: [0,18446744073709551616) 63; X64-NEXT: Determining loop execution counts for: @ptrtoint_as1 64; 65; X32-LABEL: 'ptrtoint_as1' 66; X32-NEXT: Classifying expressions for: @ptrtoint_as1 67; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64 68; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) 69; X32-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32 70; X32-NEXT: --> (ptrtoint i8 addrspace(1)* %in to i32) U: full-set S: full-set 71; X32-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16 72; X32-NEXT: --> (trunc i32 (ptrtoint i8 addrspace(1)* %in to i32) to i16) U: full-set S: full-set 73; X32-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128 74; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in to i32) to i128) U: [0,4294967296) S: [0,4294967296) 75; X32-NEXT: Determining loop execution counts for: @ptrtoint_as1 76; 77 %p0 = ptrtoint i8 addrspace(1)* %in to i64 78 %p1 = ptrtoint i8 addrspace(1)* %in to i32 79 %p2 = ptrtoint i8 addrspace(1)* %in to i16 80 %p3 = ptrtoint i8 addrspace(1)* %in to i128 81 store i64 %p0, i64* %out0 82 store i32 %p1, i32* %out1 83 store i16 %p2, i16* %out2 84 store i128 %p3, i128* %out3 85 ret void 86} 87 88; Likewise, ptrtoint of a bitcast is fine, we simply skip it. 89define void @ptrtoint_of_bitcast(i8* %in, i64* %out0) { 90; X64-LABEL: 'ptrtoint_of_bitcast' 91; X64-NEXT: Classifying expressions for: @ptrtoint_of_bitcast 92; X64-NEXT: %in_casted = bitcast i8* %in to float* 93; X64-NEXT: --> %in U: full-set S: full-set 94; X64-NEXT: %p0 = ptrtoint float* %in_casted to i64 95; X64-NEXT: --> (ptrtoint i8* %in to i64) U: full-set S: full-set 96; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast 97; 98; X32-LABEL: 'ptrtoint_of_bitcast' 99; X32-NEXT: Classifying expressions for: @ptrtoint_of_bitcast 100; X32-NEXT: %in_casted = bitcast i8* %in to float* 101; X32-NEXT: --> %in U: full-set S: full-set 102; X32-NEXT: %p0 = ptrtoint float* %in_casted to i64 103; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) 104; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast 105; 106 %in_casted = bitcast i8* %in to float* 107 %p0 = ptrtoint float* %in_casted to i64 108 store i64 %p0, i64* %out0 109 ret void 110} 111 112; addrspacecast is fine too, but We don't model addrspacecast, so we stop there. 113define void @ptrtoint_of_addrspacecast(i8* %in, i64* %out0) { 114; X64-LABEL: 'ptrtoint_of_addrspacecast' 115; X64-NEXT: Classifying expressions for: @ptrtoint_of_addrspacecast 116; X64-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)* 117; X64-NEXT: --> %in_casted U: full-set S: full-set 118; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64 119; X64-NEXT: --> (ptrtoint i8 addrspace(1)* %in_casted to i64) U: full-set S: full-set 120; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast 121; 122; X32-LABEL: 'ptrtoint_of_addrspacecast' 123; X32-NEXT: Classifying expressions for: @ptrtoint_of_addrspacecast 124; X32-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)* 125; X32-NEXT: --> %in_casted U: full-set S: full-set 126; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64 127; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in_casted to i32) to i64) U: [0,4294967296) S: [0,4294967296) 128; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast 129; 130 %in_casted = addrspacecast i8* %in to i8 addrspace(1)* 131 %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64 132 store i64 %p0, i64* %out0 133 ret void 134} 135 136; inttoptr is fine too, but we don't (and can't) model inttoptr, so we stop there. 137define void @ptrtoint_of_inttoptr(i64 %in, i64* %out0) { 138; X64-LABEL: 'ptrtoint_of_inttoptr' 139; X64-NEXT: Classifying expressions for: @ptrtoint_of_inttoptr 140; X64-NEXT: %in_casted = inttoptr i64 %in to i8* 141; X64-NEXT: --> %in_casted U: full-set S: full-set 142; X64-NEXT: %p0 = ptrtoint i8* %in_casted to i64 143; X64-NEXT: --> (ptrtoint i8* %in_casted to i64) U: full-set S: full-set 144; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr 145; 146; X32-LABEL: 'ptrtoint_of_inttoptr' 147; X32-NEXT: Classifying expressions for: @ptrtoint_of_inttoptr 148; X32-NEXT: %in_casted = inttoptr i64 %in to i8* 149; X32-NEXT: --> %in_casted U: full-set S: full-set 150; X32-NEXT: %p0 = ptrtoint i8* %in_casted to i64 151; X32-NEXT: --> (zext i32 (ptrtoint i8* %in_casted to i32) to i64) U: [0,4294967296) S: [0,4294967296) 152; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr 153; 154 %in_casted = inttoptr i64 %in to i8* 155 %p0 = ptrtoint i8* %in_casted to i64 156 store i64 %p0, i64* %out0 157 ret void 158} 159 160; A constant pointer is fine 161define void @ptrtoint_of_nullptr(i64* %out0) { 162; ALL-LABEL: 'ptrtoint_of_nullptr' 163; ALL-NEXT: Classifying expressions for: @ptrtoint_of_nullptr 164; ALL-NEXT: %p0 = ptrtoint i8* null to i64 165; ALL-NEXT: --> 0 U: [0,1) S: [0,1) 166; ALL-NEXT: Determining loop execution counts for: @ptrtoint_of_nullptr 167; 168 %p0 = ptrtoint i8* null to i64 169 store i64 %p0, i64* %out0 170 ret void 171} 172 173; A constant inttoptr argument of an ptrtoint is still bad. 174define void @ptrtoint_of_constantexpr_inttoptr(i64* %out0) { 175; X64-LABEL: 'ptrtoint_of_constantexpr_inttoptr' 176; X64-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr 177; X64-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 178; X64-NEXT: --> (ptrtoint i8* inttoptr (i64 42 to i8*) to i64) U: [42,43) S: [-64,64) 179; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr 180; 181; X32-LABEL: 'ptrtoint_of_constantexpr_inttoptr' 182; X32-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr 183; X32-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 184; X32-NEXT: --> (zext i32 (ptrtoint i8* inttoptr (i64 42 to i8*) to i32) to i64) U: [42,43) S: [0,4294967296) 185; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr 186; 187 %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 188 store i64 %p0, i64* %out0 189 ret void 190} 191 192; ptrtoint of GEP is fine. 193define void @ptrtoint_of_gep(i8* %in, i64* %out0) { 194; X64-LABEL: 'ptrtoint_of_gep' 195; X64-NEXT: Classifying expressions for: @ptrtoint_of_gep 196; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42 197; X64-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0) 198; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64 199; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64))<nuw> U: [42,0) S: [42,0) 200; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep 201; 202; X32-LABEL: 'ptrtoint_of_gep' 203; X32-NEXT: Classifying expressions for: @ptrtoint_of_gep 204; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42 205; X32-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0) 206; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64 207; X32-NEXT: --> (42 + (zext i32 (ptrtoint i8* %in to i32) to i64))<nuw><nsw> U: [42,4294967338) S: [42,4294967338) 208; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep 209; 210 %in_adj = getelementptr inbounds i8, i8* %in, i64 42 211 %p0 = ptrtoint i8* %in_adj to i64 212 store i64 %p0, i64* %out0 213 ret void 214} 215 216; It seems, we can't get ptrtoint of mul/udiv, or at least it's hard to come up with a test case. 217 218; ptrtoint of AddRec 219define void @ptrtoint_of_addrec(i32* %in, i32 %count) { 220; X64-LABEL: 'ptrtoint_of_addrec' 221; X64-NEXT: Classifying expressions for: @ptrtoint_of_addrec 222; X64-NEXT: %i3 = zext i32 %count to i64 223; X64-NEXT: --> (zext i32 %count to i64) U: [0,4294967296) S: [0,4294967296) 224; X64-NEXT: %i6 = phi i64 [ 0, %entry ], [ %i9, %loop ] 225; X64-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: (-1 + (zext i32 %count to i64))<nsw> LoopDispositions: { %loop: Computable } 226; X64-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6 227; X64-NEXT: --> {%in,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable } 228; X64-NEXT: %i8 = ptrtoint i32* %i7 to i64 229; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable } 230; X64-NEXT: %i9 = add nuw nsw i64 %i6, 1 231; X64-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable } 232; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec 233; X64-NEXT: Loop %loop: backedge-taken count is (-1 + (zext i32 %count to i64))<nsw> 234; X64-NEXT: Loop %loop: max backedge-taken count is -1 235; X64-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (zext i32 %count to i64))<nsw> 236; X64-NEXT: Predicates: 237; X64: Loop %loop: Trip multiple is 1 238; 239; X32-LABEL: 'ptrtoint_of_addrec' 240; X32-NEXT: Classifying expressions for: @ptrtoint_of_addrec 241; X32-NEXT: %i3 = zext i32 %count to i64 242; X32-NEXT: --> (zext i32 %count to i64) U: [0,4294967296) S: [0,4294967296) 243; X32-NEXT: %i6 = phi i64 [ 0, %entry ], [ %i9, %loop ] 244; X32-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: (-1 + (zext i32 %count to i64))<nsw> LoopDispositions: { %loop: Computable } 245; X32-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6 246; X32-NEXT: --> {%in,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %in) LoopDispositions: { %loop: Computable } 247; X32-NEXT: %i8 = ptrtoint i32* %i7 to i64 248; X32-NEXT: --> (zext i32 {(ptrtoint i32* %in to i32),+,4}<%loop> to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (-4 + (4 * %count) + (ptrtoint i32* %in to i32)) to i64) LoopDispositions: { %loop: Computable } 249; X32-NEXT: %i9 = add nuw nsw i64 %i6, 1 250; X32-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable } 251; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec 252; X32-NEXT: Loop %loop: backedge-taken count is (-1 + (zext i32 %count to i64))<nsw> 253; X32-NEXT: Loop %loop: max backedge-taken count is -1 254; X32-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (zext i32 %count to i64))<nsw> 255; X32-NEXT: Predicates: 256; X32: Loop %loop: Trip multiple is 1 257; 258entry: 259 %i3 = zext i32 %count to i64 260 br label %loop 261 262loop: 263 %i6 = phi i64 [ 0, %entry ], [ %i9, %loop ] 264 %i7 = getelementptr inbounds i32, i32* %in, i64 %i6 265 %i8 = ptrtoint i32* %i7 to i64 266 tail call void @use(i64 %i8) 267 %i9 = add nuw nsw i64 %i6, 1 268 %i10 = icmp eq i64 %i9, %i3 269 br i1 %i10, label %end, label %loop 270 271end: 272 ret void 273} 274declare void @use(i64) 275 276; ptrtoint of UMax 277define void @ptrtoint_of_umax(i8* %in0, i8* %in1, i64* %out0) { 278; X64-LABEL: 'ptrtoint_of_umax' 279; X64-NEXT: Classifying expressions for: @ptrtoint_of_umax 280; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 281; X64-NEXT: --> (%in0 umax %in1) U: full-set S: full-set 282; X64-NEXT: %p0 = ptrtoint i8* %s to i64 283; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) umax (ptrtoint i8* %in1 to i64)) U: full-set S: full-set 284; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umax 285; 286; X32-LABEL: 'ptrtoint_of_umax' 287; X32-NEXT: Classifying expressions for: @ptrtoint_of_umax 288; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 289; X32-NEXT: --> (%in0 umax %in1) U: full-set S: full-set 290; X32-NEXT: %p0 = ptrtoint i8* %s to i64 291; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) umax (ptrtoint i8* %in1 to i32)) to i64) U: [0,4294967296) S: [0,4294967296) 292; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_umax 293; 294 %c = icmp uge i8* %in0, %in1 295 %s = select i1 %c, i8* %in0, i8* %in1 296 %p0 = ptrtoint i8* %s to i64 297 store i64 %p0, i64* %out0 298 ret void 299} 300; ptrtoint of SMax 301define void @ptrtoint_of_smax(i8* %in0, i8* %in1, i64* %out0) { 302; X64-LABEL: 'ptrtoint_of_smax' 303; X64-NEXT: Classifying expressions for: @ptrtoint_of_smax 304; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 305; X64-NEXT: --> (%in0 smax %in1) U: full-set S: full-set 306; X64-NEXT: %p0 = ptrtoint i8* %s to i64 307; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) smax (ptrtoint i8* %in1 to i64)) U: full-set S: full-set 308; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smax 309; 310; X32-LABEL: 'ptrtoint_of_smax' 311; X32-NEXT: Classifying expressions for: @ptrtoint_of_smax 312; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 313; X32-NEXT: --> (%in0 smax %in1) U: full-set S: full-set 314; X32-NEXT: %p0 = ptrtoint i8* %s to i64 315; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) smax (ptrtoint i8* %in1 to i32)) to i64) U: [0,4294967296) S: [0,4294967296) 316; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_smax 317; 318 %c = icmp sge i8* %in0, %in1 319 %s = select i1 %c, i8* %in0, i8* %in1 320 %p0 = ptrtoint i8* %s to i64 321 store i64 %p0, i64* %out0 322 ret void 323} 324; ptrtoint of UMin 325define void @ptrtoint_of_umin(i8* %in0, i8* %in1, i64* %out0) { 326; X64-LABEL: 'ptrtoint_of_umin' 327; X64-NEXT: Classifying expressions for: @ptrtoint_of_umin 328; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 329; X64-NEXT: --> (%in0 umin %in1) U: full-set S: full-set 330; X64-NEXT: %p0 = ptrtoint i8* %s to i64 331; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) umin (ptrtoint i8* %in1 to i64)) U: full-set S: full-set 332; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umin 333; 334; X32-LABEL: 'ptrtoint_of_umin' 335; X32-NEXT: Classifying expressions for: @ptrtoint_of_umin 336; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 337; X32-NEXT: --> (%in0 umin %in1) U: full-set S: full-set 338; X32-NEXT: %p0 = ptrtoint i8* %s to i64 339; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) umin (ptrtoint i8* %in1 to i32)) to i64) U: [0,4294967296) S: [0,4294967296) 340; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_umin 341; 342 %c = icmp ule i8* %in0, %in1 343 %s = select i1 %c, i8* %in0, i8* %in1 344 %p0 = ptrtoint i8* %s to i64 345 store i64 %p0, i64* %out0 346 ret void 347} 348; ptrtoint of SMin 349define void @ptrtoint_of_smin(i8* %in0, i8* %in1, i64* %out0) { 350; X64-LABEL: 'ptrtoint_of_smin' 351; X64-NEXT: Classifying expressions for: @ptrtoint_of_smin 352; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 353; X64-NEXT: --> (%in0 smin %in1) U: full-set S: full-set 354; X64-NEXT: %p0 = ptrtoint i8* %s to i64 355; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) smin (ptrtoint i8* %in1 to i64)) U: full-set S: full-set 356; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smin 357; 358; X32-LABEL: 'ptrtoint_of_smin' 359; X32-NEXT: Classifying expressions for: @ptrtoint_of_smin 360; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 361; X32-NEXT: --> (%in0 smin %in1) U: full-set S: full-set 362; X32-NEXT: %p0 = ptrtoint i8* %s to i64 363; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) smin (ptrtoint i8* %in1 to i32)) to i64) U: [0,4294967296) S: [0,4294967296) 364; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_smin 365; 366 %c = icmp sle i8* %in0, %in1 367 %s = select i1 %c, i8* %in0, i8* %in1 368 %p0 = ptrtoint i8* %s to i64 369 store i64 %p0, i64* %out0 370 ret void 371} 372 373; void pr46786_c26_char(char* start, char *end, char *other) { 374; for (char* cur = start; cur != end; ++cur) 375; other[cur - start] += *cur; 376; } 377define void @pr46786_c26_char(i8* %arg, i8* %arg1, i8* %arg2) { 378; X64-LABEL: 'pr46786_c26_char' 379; X64-NEXT: Classifying expressions for: @pr46786_c26_char 380; X64-NEXT: %i4 = ptrtoint i8* %arg to i64 381; X64-NEXT: --> (ptrtoint i8* %arg to i64) U: full-set S: full-set 382; X64-NEXT: %i7 = phi i8* [ %arg, %bb3 ], [ %i14, %bb6 ] 383; X64-NEXT: --> {%arg,+,1}<nuw><%bb6> U: full-set S: full-set Exits: (-1 + %arg1) LoopDispositions: { %bb6: Computable } 384; X64-NEXT: %i8 = load i8, i8* %i7, align 1 385; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 386; X64-NEXT: %i9 = ptrtoint i8* %i7 to i64 387; X64-NEXT: --> {(ptrtoint i8* %arg to i64),+,1}<nuw><%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + (ptrtoint i8* %arg to i64) + %arg1) LoopDispositions: { %bb6: Computable } 388; X64-NEXT: %i10 = sub i64 %i9, %i4 389; X64-NEXT: --> {0,+,1}<nw><%bb6> U: [0,-1) S: [0,-1) Exits: (-1 + (-1 * %arg) + %arg1) LoopDispositions: { %bb6: Computable } 390; X64-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 391; X64-NEXT: --> {%arg2,+,1}<nw><%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + %arg1 + %arg2) LoopDispositions: { %bb6: Computable } 392; X64-NEXT: %i12 = load i8, i8* %i11, align 1 393; X64-NEXT: --> %i12 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 394; X64-NEXT: %i13 = add i8 %i12, %i8 395; X64-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 396; X64-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1 397; X64-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: %arg1 LoopDispositions: { %bb6: Computable } 398; X64-NEXT: Determining loop execution counts for: @pr46786_c26_char 399; X64-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * %arg) + %arg1) 400; X64-NEXT: Loop %bb6: max backedge-taken count is -2 401; X64-NEXT: Loop %bb6: Predicated backedge-taken count is (-1 + (-1 * %arg) + %arg1) 402; X64-NEXT: Predicates: 403; X64: Loop %bb6: Trip multiple is 1 404; 405; X32-LABEL: 'pr46786_c26_char' 406; X32-NEXT: Classifying expressions for: @pr46786_c26_char 407; X32-NEXT: %i4 = ptrtoint i8* %arg to i64 408; X32-NEXT: --> (zext i32 (ptrtoint i8* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) 409; X32-NEXT: %i7 = phi i8* [ %arg, %bb3 ], [ %i14, %bb6 ] 410; X32-NEXT: --> {%arg,+,1}<nuw><%bb6> U: full-set S: full-set Exits: (-1 + %arg1) LoopDispositions: { %bb6: Computable } 411; X32-NEXT: %i8 = load i8, i8* %i7, align 1 412; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 413; X32-NEXT: %i9 = ptrtoint i8* %i7 to i64 414; X32-NEXT: --> {(zext i32 (ptrtoint i8* %arg to i32) to i64),+,1}<nuw><%bb6> U: [0,8589934590) S: [0,8589934590) Exits: ((zext i8* (-1 + (-1 * %arg) + %arg1) to i64) + (zext i32 (ptrtoint i8* %arg to i32) to i64)) LoopDispositions: { %bb6: Computable } 415; X32-NEXT: %i10 = sub i64 %i9, %i4 416; X32-NEXT: --> {0,+,1}<nw><%bb6> U: [0,4294967295) S: [0,4294967295) Exits: (zext i8* (-1 + (-1 * %arg) + %arg1) to i64) LoopDispositions: { %bb6: Computable } 417; X32-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 418; X32-NEXT: --> {%arg2,+,1}<%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + %arg1 + %arg2) LoopDispositions: { %bb6: Computable } 419; X32-NEXT: %i12 = load i8, i8* %i11, align 1 420; X32-NEXT: --> %i12 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 421; X32-NEXT: %i13 = add i8 %i12, %i8 422; X32-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 423; X32-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1 424; X32-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: %arg1 LoopDispositions: { %bb6: Computable } 425; X32-NEXT: Determining loop execution counts for: @pr46786_c26_char 426; X32-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * %arg) + %arg1) 427; X32-NEXT: Loop %bb6: max backedge-taken count is -2 428; X32-NEXT: Loop %bb6: Predicated backedge-taken count is (-1 + (-1 * %arg) + %arg1) 429; X32-NEXT: Predicates: 430; X32: Loop %bb6: Trip multiple is 1 431; 432 %i = icmp eq i8* %arg, %arg1 433 br i1 %i, label %bb5, label %bb3 434 435bb3: 436 %i4 = ptrtoint i8* %arg to i64 437 br label %bb6 438 439bb6: 440 %i7 = phi i8* [ %arg, %bb3 ], [ %i14, %bb6 ] 441 %i8 = load i8, i8* %i7 442 %i9 = ptrtoint i8* %i7 to i64 443 %i10 = sub i64 %i9, %i4 444 %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 445 %i12 = load i8, i8* %i11 446 %i13 = add i8 %i12, %i8 447 store i8 %i13, i8* %i11 448 %i14 = getelementptr inbounds i8, i8* %i7, i64 1 449 %i15 = icmp eq i8* %i14, %arg1 450 br i1 %i15, label %bb5, label %bb6 451 452bb5: 453 ret void 454} 455 456; void pr46786_c26_int(int* start, int *end, int *other) { 457; for (int* cur = start; cur != end; ++cur) 458; other[cur - start] += *cur; 459; } 460; 461; FIXME: 4 * (%i10 EXACT/s 4) is just %i10 462define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) { 463; X64-LABEL: 'pr46786_c26_int' 464; X64-NEXT: Classifying expressions for: @pr46786_c26_int 465; X64-NEXT: %i4 = ptrtoint i32* %arg to i64 466; X64-NEXT: --> (ptrtoint i32* %arg to i64) U: full-set S: full-set 467; X64-NEXT: %i7 = phi i32* [ %arg, %bb3 ], [ %i15, %bb6 ] 468; X64-NEXT: --> {%arg,+,4}<nuw><%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable } 469; X64-NEXT: %i8 = load i32, i32* %i7, align 4 470; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 471; X64-NEXT: %i9 = ptrtoint i32* %i7 to i64 472; X64-NEXT: --> {(ptrtoint i32* %arg to i64),+,4}<nuw><%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + (ptrtoint i32* %arg to i64)) LoopDispositions: { %bb6: Computable } 473; X64-NEXT: %i10 = sub i64 %i9, %i4 474; X64-NEXT: --> {0,+,4}<nw><%bb6> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> LoopDispositions: { %bb6: Computable } 475; X64-NEXT: %i11 = ashr exact i64 %i10, 2 476; X64-NEXT: --> ((({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>)))<nsw> U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: ((((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>)))<nsw> LoopDispositions: { %bb6: Computable } 477; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 478; X64-NEXT: --> ((4 * (({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>))) + %arg2) U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>))) + %arg2) LoopDispositions: { %bb6: Computable } 479; X64-NEXT: %i13 = load i32, i32* %i12, align 4 480; X64-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 481; X64-NEXT: %i14 = add nsw i32 %i13, %i8 482; X64-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 483; X64-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1 484; X64-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable } 485; X64-NEXT: Determining loop execution counts for: @pr46786_c26_int 486; X64-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4) 487; X64-NEXT: Loop %bb6: max backedge-taken count is 4611686018427387903 488; X64-NEXT: Loop %bb6: Predicated backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4) 489; X64-NEXT: Predicates: 490; X64: Loop %bb6: Trip multiple is 1 491; 492; X32-LABEL: 'pr46786_c26_int' 493; X32-NEXT: Classifying expressions for: @pr46786_c26_int 494; X32-NEXT: %i4 = ptrtoint i32* %arg to i64 495; X32-NEXT: --> (zext i32 (ptrtoint i32* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) 496; X32-NEXT: %i7 = phi i32* [ %arg, %bb3 ], [ %i15, %bb6 ] 497; X32-NEXT: --> {%arg,+,4}<nuw><%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable } 498; X32-NEXT: %i8 = load i32, i32* %i7, align 4 499; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 500; X32-NEXT: %i9 = ptrtoint i32* %i7 to i64 501; X32-NEXT: --> {(zext i32 (ptrtoint i32* %arg to i32) to i64),+,4}<nuw><%bb6> U: [0,8589934588) S: [0,8589934588) Exits: ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>) LoopDispositions: { %bb6: Computable } 502; X32-NEXT: %i10 = sub i64 %i9, %i4 503; X32-NEXT: --> {0,+,4}<nw><%bb6> U: [0,4294967293) S: [0,4294967293) Exits: (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw> LoopDispositions: { %bb6: Computable } 504; X32-NEXT: %i11 = ashr exact i64 %i10, 2 505; X32-NEXT: --> ({0,+,1}<nw><%bb6> * (1 smin {0,+,4}<nuw><nsw><%bb6>))<nuw><nsw> U: [0,1073741824) S: [0,1073741824) Exits: (((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4) * (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>))<nuw><nsw> LoopDispositions: { %bb6: Computable } 506; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 507; X32-NEXT: --> (((trunc i64 (1 smin {0,+,4}<nuw><nsw><%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2) U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg2) LoopDispositions: { %bb6: Computable } 508; X32-NEXT: %i13 = load i32, i32* %i12, align 4 509; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 510; X32-NEXT: %i14 = add nsw i32 %i13, %i8 511; X32-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant } 512; X32-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1 513; X32-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable } 514; X32-NEXT: Determining loop execution counts for: @pr46786_c26_int 515; X32-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4) 516; X32-NEXT: Loop %bb6: max backedge-taken count is 1073741823 517; X32-NEXT: Loop %bb6: Predicated backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4) 518; X32-NEXT: Predicates: 519; X32: Loop %bb6: Trip multiple is 1 520; 521 %i = icmp eq i32* %arg, %arg1 522 br i1 %i, label %bb5, label %bb3 523 524bb3: 525 %i4 = ptrtoint i32* %arg to i64 526 br label %bb6 527 528bb6: 529 %i7 = phi i32* [ %arg, %bb3 ], [ %i15, %bb6 ] 530 %i8 = load i32, i32* %i7 531 %i9 = ptrtoint i32* %i7 to i64 532 %i10 = sub i64 %i9, %i4 533 %i11 = ashr exact i64 %i10, 2 534 %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 535 %i13 = load i32, i32* %i12 536 %i14 = add nsw i32 %i13, %i8 537 store i32 %i14, i32* %i12 538 %i15 = getelementptr inbounds i32, i32* %i7, i64 1 539 %i16 = icmp eq i32* %i15, %arg1 540 br i1 %i16, label %bb5, label %bb6 541 542bb5: 543 ret void 544} 545 546; During SCEV rewrites, we could end up calling `ScalarEvolution::getPtrToIntExpr()` 547; on an integer. Make sure we handle that case gracefully. 548define void @ptrtoint_of_integer(i8* %arg, i64 %arg1, i1 %arg2) local_unnamed_addr { 549; X64-LABEL: 'ptrtoint_of_integer' 550; X64-NEXT: Classifying expressions for: @ptrtoint_of_integer 551; X64-NEXT: %i4 = ptrtoint i8* %arg to i64 552; X64-NEXT: --> (ptrtoint i8* %arg to i64) U: full-set S: full-set 553; X64-NEXT: %i6 = sub i64 %i4, %arg1 554; X64-NEXT: --> ((-1 * %arg1) + (ptrtoint i8* %arg to i64)) U: full-set S: full-set 555; X64-NEXT: %i9 = phi i64 [ 1, %bb7 ], [ %i11, %bb10 ] 556; X64-NEXT: --> {1,+,1}<nuw><%bb8> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb8: Computable } 557; X64-NEXT: %i11 = add nuw i64 %i9, 1 558; X64-NEXT: --> {2,+,1}<nw><%bb8> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb8: Computable } 559; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_integer 560; X64-NEXT: Loop %bb8: <multiple exits> Unpredictable backedge-taken count. 561; X64-NEXT: exit count for bb8: ***COULDNOTCOMPUTE*** 562; X64-NEXT: exit count for bb10: (-2 + (-1 * %arg1) + (ptrtoint i8* %arg to i64)) 563; X64-NEXT: Loop %bb8: max backedge-taken count is -1 564; X64-NEXT: Loop %bb8: Unpredictable predicated backedge-taken count. 565; 566; X32-LABEL: 'ptrtoint_of_integer' 567; X32-NEXT: Classifying expressions for: @ptrtoint_of_integer 568; X32-NEXT: %i4 = ptrtoint i8* %arg to i64 569; X32-NEXT: --> (zext i32 (ptrtoint i8* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) 570; X32-NEXT: %i6 = sub i64 %i4, %arg1 571; X32-NEXT: --> ((zext i32 (ptrtoint i8* %arg to i32) to i64) + (-1 * %arg1)) U: full-set S: full-set 572; X32-NEXT: %i9 = phi i64 [ 1, %bb7 ], [ %i11, %bb10 ] 573; X32-NEXT: --> {1,+,1}<nuw><%bb8> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb8: Computable } 574; X32-NEXT: %i11 = add nuw i64 %i9, 1 575; X32-NEXT: --> {2,+,1}<nw><%bb8> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb8: Computable } 576; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_integer 577; X32-NEXT: Loop %bb8: <multiple exits> Unpredictable backedge-taken count. 578; X32-NEXT: exit count for bb8: ***COULDNOTCOMPUTE*** 579; X32-NEXT: exit count for bb10: (-2 + (zext i32 (ptrtoint i8* %arg to i32) to i64) + (-1 * %arg1)) 580; X32-NEXT: Loop %bb8: max backedge-taken count is -1 581; X32-NEXT: Loop %bb8: Unpredictable predicated backedge-taken count. 582; 583bb: 584 %i = icmp eq i8* %arg, null 585 br i1 %i, label %bb14, label %bb3 586 587bb3: ; preds = %bb 588 %i4 = ptrtoint i8* %arg to i64 589 br label %bb5 590 591bb5: ; preds = %bb3 592 %i6 = sub i64 %i4, %arg1 593 br label %bb7 594 595bb7: ; preds = %bb5 596 br label %bb8 597 598bb8: ; preds = %bb10, %bb7 599 %i9 = phi i64 [ 1, %bb7 ], [ %i11, %bb10 ] 600 br i1 %arg2, label %bb10, label %bb13 601 602bb10: ; preds = %bb8 603 %i11 = add nuw i64 %i9, 1 604 %i12 = icmp eq i64 %i11, %i6 605 br i1 %i12, label %bb13, label %bb8 606 607bb13: ; preds = %bb10, %bb8 608 ret void 609 610bb14: ; preds = %bb 611 ret void 612} 613