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