1; "PLAIN" - No optimizations. This tests the default target layout 2; constant folder. 3; RUN: opt -S -o - < %s | FileCheck --check-prefix=PLAIN %s 4 5; "OPT" - Optimizations but no targetdata. This tests default target layout 6; folding in the optimizers. 7; RUN: opt -S -o - -passes='function(instcombine),globalopt' < %s | FileCheck --check-prefix=OPT %s 8 9; "TO" - Optimizations and targetdata. This tests target-dependent 10; folding in the optimizers. 11; RUN: opt -S -o - -passes='function(instcombine),globalopt' -data-layout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" < %s | FileCheck --check-prefix=TO %s 12 13; "SCEV" - ScalarEvolution with default target layout 14; RUN: opt -passes='print<scalar-evolution>' < %s -disable-output 2>&1 | FileCheck --check-prefix=SCEV %s 15 16 17; The automatic constant folder in opt does not have targetdata access, so 18; it can't fold gep arithmetic, in general. However, the constant folder run 19; from instcombine and global opt can use targetdata. 20 21; PLAIN: @G8 = global ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -1) 22; PLAIN: @G1 = global ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -1) 23; PLAIN: @F8 = global ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -2) 24; PLAIN: @F1 = global ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -2) 25; PLAIN: @H8 = global ptr getelementptr (i8, ptr null, i32 -1) 26; PLAIN: @H1 = global ptr getelementptr (i1, ptr null, i32 -1) 27; OPT: @G8 = local_unnamed_addr global ptr null 28; OPT: @G1 = local_unnamed_addr global ptr null 29; OPT: @F8 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 30; OPT: @F1 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 31; OPT: @H8 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 32; OPT: @H1 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 33; TO: @G8 = local_unnamed_addr global ptr null 34; TO: @G1 = local_unnamed_addr global ptr null 35; TO: @F8 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 36; TO: @F1 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 37; TO: @H8 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 38; TO: @H1 = local_unnamed_addr global ptr inttoptr (i64 -1 to ptr) 39 40@G8 = global ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -1) 41@G1 = global ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -1) 42@F8 = global ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -2) 43@F1 = global ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -2) 44@H8 = global ptr getelementptr (i8, ptr inttoptr (i32 0 to ptr), i32 -1) 45@H1 = global ptr getelementptr (i1, ptr inttoptr (i32 0 to ptr), i32 -1) 46 47; The target-independent folder should be able to do some clever 48; simplifications on sizeof, alignof, and offsetof expressions. The 49; target-dependent folder should fold these down to constants. 50 51; PLAIN: @a = constant i64 mul (i64 ptrtoint (ptr getelementptr ({ [7 x double], [7 x double] }, ptr null, i64 11) to i64), i64 15) 52; PLAIN: @b = constant i64 ptrtoint (ptr getelementptr ({ i1, [13 x double] }, ptr null, i64 0, i32 1) to i64) 53; PLAIN: @c = constant i64 ptrtoint (ptr getelementptr ({ double, double, double, double }, ptr null, i64 0, i32 2) to i64) 54; PLAIN: @d = constant i64 ptrtoint (ptr getelementptr ([13 x double], ptr null, i64 0, i32 11) to i64) 55; PLAIN: @e = constant i64 ptrtoint (ptr getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64) 56; PLAIN: @f = constant i64 ptrtoint (ptr getelementptr ({ i1, <{ i16, i128 }> }, ptr null, i64 0, i32 1) to i64) 57; PLAIN: @g = constant i64 ptrtoint (ptr getelementptr ({ i1, { double, double } }, ptr null, i64 0, i32 1) to i64) 58; PLAIN: @h = constant i64 ptrtoint (ptr getelementptr (ptr, ptr null, i64 1) to i64) 59; PLAIN: @i = constant i64 ptrtoint (ptr getelementptr ({ i1, ptr }, ptr null, i64 0, i32 1) to i64) 60; OPT: @a = local_unnamed_addr constant i64 18480 61; OPT: @b = local_unnamed_addr constant i64 8 62; OPT: @c = local_unnamed_addr constant i64 16 63; OPT: @d = local_unnamed_addr constant i64 88 64; OPT: @e = local_unnamed_addr constant i64 16 65; OPT: @f = local_unnamed_addr constant i64 1 66; OPT: @g = local_unnamed_addr constant i64 8 67; OPT: @h = local_unnamed_addr constant i64 8 68; OPT: @i = local_unnamed_addr constant i64 8 69; TO: @a = local_unnamed_addr constant i64 18480 70; TO: @b = local_unnamed_addr constant i64 8 71; TO: @c = local_unnamed_addr constant i64 16 72; TO: @d = local_unnamed_addr constant i64 88 73; TO: @e = local_unnamed_addr constant i64 16 74; TO: @f = local_unnamed_addr constant i64 1 75; TO: @g = local_unnamed_addr constant i64 8 76; TO: @h = local_unnamed_addr constant i64 8 77; TO: @i = local_unnamed_addr constant i64 8 78 79@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr getelementptr ({[7 x double], [7 x double]}, ptr null, i64 11) to i64), i64 5)) 80@b = constant i64 ptrtoint (ptr getelementptr ({i1, [13 x double]}, ptr null, i64 0, i32 1) to i64) 81@c = constant i64 ptrtoint (ptr getelementptr ({double, double, double, double}, ptr null, i64 0, i32 2) to i64) 82@d = constant i64 ptrtoint (ptr getelementptr ([13 x double], ptr null, i64 0, i32 11) to i64) 83@e = constant i64 ptrtoint (ptr getelementptr ({double, float, double, double}, ptr null, i64 0, i32 2) to i64) 84@f = constant i64 ptrtoint (ptr getelementptr ({i1, <{ i16, i128 }>}, ptr null, i64 0, i32 1) to i64) 85@g = constant i64 ptrtoint (ptr getelementptr ({i1, {double, double}}, ptr null, i64 0, i32 1) to i64) 86@h = constant i64 ptrtoint (ptr getelementptr (ptr, ptr null, i64 1) to i64) 87@i = constant i64 ptrtoint (ptr getelementptr ({i1, ptr}, ptr null, i64 0, i32 1) to i64) 88 89; The target-dependent folder should cast GEP indices to integer-sized pointers. 90 91; PLAIN: @M = constant ptr getelementptr (i64, ptr null, i32 1) 92; PLAIN: @N = constant ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) 93; PLAIN: @O = constant ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) 94; OPT: @M = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 95; OPT: @N = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 96; OPT: @O = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 97; TO: @M = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 98; TO: @N = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 99; TO: @O = local_unnamed_addr constant ptr inttoptr (i64 8 to ptr) 100 101@M = constant ptr getelementptr (i64, ptr null, i32 1) 102@N = constant ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) 103@O = constant ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) 104 105; Fold GEP of a GEP. Very simple cases are folded without targetdata. 106 107; PLAIN: @Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 1), i64 1) 108; PLAIN: @Z = global ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) 109; OPT: @Y = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 48) 110; OPT: @Z = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12) 111; TO: @Y = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 48) 112; TO: @Z = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12) 113 114@ext = external global [3 x { i32, i32 }] 115@Y = global ptr getelementptr inbounds ([3 x { i32, i32 }], ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 1), i64 1) 116@Z = global ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) 117 118; Duplicate all of the above as function return values rather than 119; global initializers. 120 121; PLAIN: define ptr @goo8() #0 { 122; PLAIN: %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 123; PLAIN: ret ptr %t 124; PLAIN: } 125; PLAIN: define ptr @goo1() #0 { 126; PLAIN: %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 127; PLAIN: ret ptr %t 128; PLAIN: } 129; PLAIN: define ptr @foo8() #0 { 130; PLAIN: %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 131; PLAIN: ret ptr %t 132; PLAIN: } 133; PLAIN: define ptr @foo1() #0 { 134; PLAIN: %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 135; PLAIN: ret ptr %t 136; PLAIN: } 137; PLAIN: define ptr @hoo8() #0 { 138; PLAIN: %t = bitcast ptr getelementptr (i8, ptr null, i32 -1) to ptr 139; PLAIN: ret ptr %t 140; PLAIN: } 141; PLAIN: define ptr @hoo1() #0 { 142; PLAIN: %t = bitcast ptr getelementptr (i1, ptr null, i32 -1) to ptr 143; PLAIN: ret ptr %t 144; PLAIN: } 145; OPT: define ptr @goo8() local_unnamed_addr #0 { 146; OPT: ret ptr null 147; OPT: } 148; OPT: define ptr @goo1() local_unnamed_addr #0 { 149; OPT: ret ptr null 150; OPT: } 151; OPT: define ptr @foo8() local_unnamed_addr #0 { 152; OPT: ret ptr inttoptr (i64 -1 to ptr) 153; OPT: } 154; OPT: define ptr @foo1() local_unnamed_addr #0 { 155; OPT: ret ptr inttoptr (i64 -1 to ptr) 156; OPT: } 157; OPT: define ptr @hoo8() local_unnamed_addr #0 { 158; OPT: ret ptr inttoptr (i64 -1 to ptr) 159; OPT: } 160; OPT: define ptr @hoo1() local_unnamed_addr #0 { 161; OPT: ret ptr inttoptr (i64 -1 to ptr) 162; OPT: } 163; TO: define ptr @goo8() local_unnamed_addr #0 { 164; TO: ret ptr null 165; TO: } 166; TO: define ptr @goo1() local_unnamed_addr #0 { 167; TO: ret ptr null 168; TO: } 169; TO: define ptr @foo8() local_unnamed_addr #0 { 170; TO: ret ptr inttoptr (i64 -1 to ptr) 171; TO: } 172; TO: define ptr @foo1() local_unnamed_addr #0 { 173; TO: ret ptr inttoptr (i64 -1 to ptr) 174; TO: } 175; TO: define ptr @hoo8() local_unnamed_addr #0 { 176; TO: ret ptr inttoptr (i64 -1 to ptr) 177; TO: } 178; TO: define ptr @hoo1() local_unnamed_addr #0 { 179; TO: ret ptr inttoptr (i64 -1 to ptr) 180; TO: } 181; SCEV: Classifying expressions for: @goo8 182; SCEV: %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 183; SCEV: --> (-1 + inttoptr (i32 1 to ptr)) 184; SCEV: Classifying expressions for: @goo1 185; SCEV: %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 186; SCEV: --> (-1 + inttoptr (i32 1 to ptr)) 187; SCEV: Classifying expressions for: @foo8 188; SCEV: %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 189; SCEV: --> (-2 + inttoptr (i32 1 to ptr)) 190; SCEV: Classifying expressions for: @foo1 191; SCEV: %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 192; SCEV: --> (-2 + inttoptr (i32 1 to ptr)) 193; SCEV: Classifying expressions for: @hoo8 194; SCEV: --> (-1 + null)<nuw><nsw> U: [-1,0) S: [-1,0) 195; SCEV: Classifying expressions for: @hoo1 196; SCEV: --> (-1 + null)<nuw><nsw> U: [-1,0) S: [-1,0) 197 198define ptr @goo8() nounwind { 199 %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 200 ret ptr %t 201} 202define ptr @goo1() nounwind { 203 %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -1) to ptr 204 ret ptr %t 205} 206define ptr @foo8() nounwind { 207 %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 208 ret ptr %t 209} 210define ptr @foo1() nounwind { 211 %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 1 to ptr), i32 -2) to ptr 212 ret ptr %t 213} 214define ptr @hoo8() nounwind { 215 %t = bitcast ptr getelementptr (i8, ptr inttoptr (i32 0 to ptr), i32 -1) to ptr 216 ret ptr %t 217} 218define ptr @hoo1() nounwind { 219 %t = bitcast ptr getelementptr (i1, ptr inttoptr (i32 0 to ptr), i32 -1) to ptr 220 ret ptr %t 221} 222 223; PLAIN: define i64 @fa() #0 { 224; PLAIN: %t = bitcast i64 mul (i64 ptrtoint (ptr getelementptr ({ [7 x double], [7 x double] }, ptr null, i64 11) to i64), i64 15) to i64 225; PLAIN: ret i64 %t 226; PLAIN: } 227; PLAIN: define i64 @fb() #0 { 228; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, [13 x double] }, ptr null, i64 0, i32 1) to i64) to i64 229; PLAIN: ret i64 %t 230; PLAIN: } 231; PLAIN: define i64 @fc() #0 { 232; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ double, double, double, double }, ptr null, i64 0, i32 2) to i64) to i64 233; PLAIN: ret i64 %t 234; PLAIN: } 235; PLAIN: define i64 @fd() #0 { 236; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ([13 x double], ptr null, i64 0, i32 11) to i64) to i64 237; PLAIN: ret i64 %t 238; PLAIN: } 239; PLAIN: define i64 @fe() #0 { 240; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64) to i64 241; PLAIN: ret i64 %t 242; PLAIN: } 243; PLAIN: define i64 @ff() #0 { 244; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, <{ i16, i128 }> }, ptr null, i64 0, i32 1) to i64) to i64 245; PLAIN: ret i64 %t 246; PLAIN: } 247; PLAIN: define i64 @fg() #0 { 248; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, { double, double } }, ptr null, i64 0, i32 1) to i64) to i64 249; PLAIN: ret i64 %t 250; PLAIN: } 251; PLAIN: define i64 @fh() #0 { 252; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64) to i64 253; PLAIN: ret i64 %t 254; PLAIN: } 255; PLAIN: define i64 @fi() #0 { 256; PLAIN: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, ptr }, ptr null, i64 0, i32 1) to i64) to i64 257; PLAIN: ret i64 %t 258; PLAIN: } 259; OPT: define i64 @fa() local_unnamed_addr #0 { 260; OPT: ret i64 18480 261; OPT: } 262; OPT: define i64 @fb() local_unnamed_addr #0 { 263; OPT: ret i64 8 264; OPT: } 265; OPT: define i64 @fc() local_unnamed_addr #0 { 266; OPT: ret i64 16 267; OPT: } 268; OPT: define i64 @fd() local_unnamed_addr #0 { 269; OPT: ret i64 88 270; OPT: } 271; OPT: define i64 @fe() local_unnamed_addr #0 { 272; OPT: ret i64 16 273; OPT: } 274; OPT: define i64 @ff() local_unnamed_addr #0 { 275; OPT: ret i64 1 276; OPT: } 277; OPT: define i64 @fg() local_unnamed_addr #0 { 278; OPT: ret i64 8 279; OPT: } 280; OPT: define i64 @fh() local_unnamed_addr #0 { 281; OPT: ret i64 8 282; OPT: } 283; OPT: define i64 @fi() local_unnamed_addr #0 { 284; OPT: ret i64 8 285; OPT: } 286; TO: define i64 @fa() local_unnamed_addr #0 { 287; TO: ret i64 18480 288; TO: } 289; TO: define i64 @fb() local_unnamed_addr #0 { 290; TO: ret i64 8 291; TO: } 292; TO: define i64 @fc() local_unnamed_addr #0 { 293; TO: ret i64 16 294; TO: } 295; TO: define i64 @fd() local_unnamed_addr #0 { 296; TO: ret i64 88 297; TO: } 298; TO: define i64 @fe() local_unnamed_addr #0 { 299; TO: ret i64 16 300; TO: } 301; TO: define i64 @ff() local_unnamed_addr #0 { 302; TO: ret i64 1 303; TO: } 304; TO: define i64 @fg() local_unnamed_addr #0 { 305; TO: ret i64 8 306; TO: } 307; TO: define i64 @fh() local_unnamed_addr #0 { 308; TO: ret i64 8 309; TO: } 310; TO: define i64 @fi() local_unnamed_addr #0 { 311; TO: ret i64 8 312; TO: } 313; SCEV-LABEL: Classifying expressions for: @fa 314; SCEV: %t = bitcast i64 mul (i64 ptrtoint (ptr getelementptr ({ [7 x double], [7 x double] }, ptr null, i64 11) to i64), i64 15) to i64 315; SCEV: --> 18480 316; SCEV-LABEL: Classifying expressions for: @fb 317; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, [13 x double] }, ptr null, i64 0, i32 1) to i64) to i64 318; SCEV: --> 8 319; SCEV-LABEL: Classifying expressions for: @fc 320; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ double, double, double, double }, ptr null, i64 0, i32 2) to i64) to i64 321; SCEV: --> 16 322; SCEV-LABEL: Classifying expressions for: @fd 323; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ([13 x double], ptr null, i64 0, i32 11) to i64) to i64 324; SCEV: --> 88 325; SCEV-LABEL: Classifying expressions for: @fe 326; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64) to i64 327; SCEV: --> 16 328; SCEV-LABEL: Classifying expressions for: @ff 329; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, <{ i16, i128 }> }, ptr null, i64 0, i32 1) to i64) to i64 330; SCEV: --> 1 331; SCEV-LABEL: Classifying expressions for: @fg 332; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, { double, double } }, ptr null, i64 0, i32 1) to i64) to i64 333; SCEV: --> 8 334; SCEV-LABEL: Classifying expressions for: @fh 335; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64) to i64 336; SCEV: --> 8 337; SCEV-LABEL: Classifying expressions for: @fi 338; SCEV: %t = bitcast i64 ptrtoint (ptr getelementptr ({ i1, ptr }, ptr null, i64 0, i32 1) to i64) to i64 339; SCEV: --> 8 340 341define i64 @fa() nounwind { 342 %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr getelementptr ({[7 x double], [7 x double]}, ptr null, i64 11) to i64), i64 5)) to i64 343 ret i64 %t 344} 345define i64 @fb() nounwind { 346 %t = bitcast i64 ptrtoint (ptr getelementptr ({i1, [13 x double]}, ptr null, i64 0, i32 1) to i64) to i64 347 ret i64 %t 348} 349define i64 @fc() nounwind { 350 %t = bitcast i64 ptrtoint (ptr getelementptr ({double, double, double, double}, ptr null, i64 0, i32 2) to i64) to i64 351 ret i64 %t 352} 353define i64 @fd() nounwind { 354 %t = bitcast i64 ptrtoint (ptr getelementptr ([13 x double], ptr null, i64 0, i32 11) to i64) to i64 355 ret i64 %t 356} 357define i64 @fe() nounwind { 358 %t = bitcast i64 ptrtoint (ptr getelementptr ({double, float, double, double}, ptr null, i64 0, i32 2) to i64) to i64 359 ret i64 %t 360} 361define i64 @ff() nounwind { 362 %t = bitcast i64 ptrtoint (ptr getelementptr ({i1, <{ i16, i128 }>}, ptr null, i64 0, i32 1) to i64) to i64 363 ret i64 %t 364} 365define i64 @fg() nounwind { 366 %t = bitcast i64 ptrtoint (ptr getelementptr ({i1, {double, double}}, ptr null, i64 0, i32 1) to i64) to i64 367 ret i64 %t 368} 369define i64 @fh() nounwind { 370 %t = bitcast i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64) to i64 371 ret i64 %t 372} 373define i64 @fi() nounwind { 374 %t = bitcast i64 ptrtoint (ptr getelementptr ({i1, ptr}, ptr null, i64 0, i32 1) to i64) to i64 375 ret i64 %t 376} 377 378; PLAIN: define ptr @fM() #0 { 379; PLAIN: %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr 380; PLAIN: ret ptr %t 381; PLAIN: } 382; PLAIN: define ptr @fN() #0 { 383; PLAIN: %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr 384; PLAIN: ret ptr %t 385; PLAIN: } 386; PLAIN: define ptr @fO() #0 { 387; PLAIN: %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr 388; PLAIN: ret ptr %t 389; PLAIN: } 390; OPT: define ptr @fM() local_unnamed_addr #0 { 391; OPT: ret ptr inttoptr (i64 8 to ptr) 392; OPT: } 393; OPT: define ptr @fN() local_unnamed_addr #0 { 394; OPT: ret ptr inttoptr (i64 8 to ptr) 395; OPT: } 396; OPT: define ptr @fO() local_unnamed_addr #0 { 397; OPT: ret ptr inttoptr (i64 8 to ptr) 398; OPT: } 399; TO: define ptr @fM() local_unnamed_addr #0 { 400; TO: ret ptr inttoptr (i64 8 to ptr) 401; TO: } 402; TO: define ptr @fN() local_unnamed_addr #0 { 403; TO: ret ptr inttoptr (i64 8 to ptr) 404; TO: } 405; TO: define ptr @fO() local_unnamed_addr #0 { 406; TO: ret ptr inttoptr (i64 8 to ptr) 407; TO: } 408; SCEV: Classifying expressions for: @fM 409; SCEV: %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr 410; SCEV: --> (8 + null)<nuw><nsw> U: [8,9) S: [8,9) 411; SCEV: Classifying expressions for: @fN 412; SCEV: %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr 413; SCEV: --> (8 + null)<nuw><nsw> U: [8,9) S: [8,9) 414; SCEV: Classifying expressions for: @fO 415; SCEV: %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr 416; SCEV: --> (8 + null)<nuw><nsw> U: [8,9) S: [8,9) 417 418define ptr @fM() nounwind { 419 %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr 420 ret ptr %t 421} 422define ptr @fN() nounwind { 423 %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr 424 ret ptr %t 425} 426define ptr @fO() nounwind { 427 %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr 428 ret ptr %t 429} 430 431; PLAIN: define ptr @fZ() #0 { 432; PLAIN: %t = bitcast ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) to ptr 433; PLAIN: ret ptr %t 434; PLAIN: } 435; OPT: define ptr @fZ() local_unnamed_addr #0 { 436; OPT: ret ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12) 437; OPT: } 438; TO: define ptr @fZ() local_unnamed_addr #0 { 439; TO: ret ptr getelementptr inbounds nuw (i8, ptr @ext, i64 12) 440; TO: } 441; SCEV: Classifying expressions for: @fZ 442; SCEV: %t = bitcast ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) to ptr 443; SCEV: --> (12 + @ext) 444 445define ptr @fZ() nounwind { 446 %t = bitcast ptr getelementptr inbounds (i32, ptr getelementptr inbounds ([3 x { i32, i32 }], ptr @ext, i64 0, i64 1, i32 0), i64 1) to ptr 447 ret ptr %t 448} 449 450; PR15262 - Check GEP folding with casts between address spaces. 451 452@p0 = global [4 x i8] zeroinitializer, align 1 453@p12 = addrspace(12) global [4 x i8] zeroinitializer, align 1 454 455define ptr @different_addrspace() nounwind noinline { 456; OPT: different_addrspace 457 %p = getelementptr inbounds i8, ptr addrspacecast (ptr addrspace(12) @p12 to ptr), 458 i32 2 459 ret ptr %p 460; OPT: ret ptr getelementptr inbounds nuw (i8, ptr addrspacecast (ptr addrspace(12) @p12 to ptr), i64 2) 461} 462 463define ptr @same_addrspace() nounwind noinline { 464; OPT: same_addrspace 465 %p = getelementptr inbounds i8, ptr @p0, i32 2 466 ret ptr %p 467; OPT: ret ptr getelementptr inbounds nuw (i8, ptr @p0, i64 2) 468} 469 470@gv1 = internal global i32 1 471@gv2 = internal global [1 x i32] [ i32 2 ] 472@gv3 = internal global [1 x i32] [ i32 2 ] 473 474define i1 @gv_gep_vs_gv() { 475 %cmp = icmp eq ptr @gv2, @gv1 476 ret i1 %cmp 477} 478; OPT: gv_gep_vs_gv 479; OPT: ret i1 false 480 481define i1 @gv_gep_vs_gv_gep() { 482 %cmp = icmp eq ptr @gv2, @gv3 483 ret i1 %cmp 484} 485; OPT: gv_gep_vs_gv_gep 486; OPT: ret i1 false 487 488; CHECK: attributes #0 = { nounwind } 489