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