1; "PLAIN" - No optimizations. This tests the target-independent 2; constant folder. 3; RUN: opt -S -o - %s | FileCheck --check-prefix=PLAIN %s 4 5target datalayout = "e-p:128:128:128-p1:32:32:32-p2:8:8:8-p3:16:16:16-p4:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32" 6 7; The automatic constant folder in opt does not have targetdata access, so 8; it can't fold gep arithmetic, in general. However, the constant folder run 9; from instcombine and global opt can use targetdata. 10; PLAIN: @G8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) 11@G8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) 12; PLAIN: @G1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -1) 13@G1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -1) 14; PLAIN: @F8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) 15@F8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) 16; PLAIN: @F1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -2) 17@F1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 1 to ptr addrspace(2)), i8 -2) 18; PLAIN: @H8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i32 -1) 19@H8 = global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 0 to ptr addrspace(1)), i32 -1) 20; PLAIN: @H1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i8 -1) 21@H1 = global ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i8 0 to ptr addrspace(2)), i8 -1) 22 23 24; The target-independent folder should be able to do some clever 25; simplifications on sizeof, alignof, and offsetof expressions. The 26; target-dependent folder should fold these down to constants. 27; PLAIN-X: @a = constant i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2310) 28@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr ({[7 x double], [7 x double]}, ptr addrspace(4) null, i64 11) to i64), i64 5)) 29 30; PLAIN-X: @b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64) 31@b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64) 32 33; PLAIN-X: @c = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2) 34@c = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, double, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) 35 36; PLAIN-X: @d = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 11) 37@d = constant i64 ptrtoint (ptr addrspace(4) getelementptr ([13 x double], ptr addrspace(4) null, i64 0, i32 11) to i64) 38 39; PLAIN-X: @e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64) 40@e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, float, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) 41 42; PLAIN-X: @f = constant i64 1 43@f = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, <{ i16, i128 }>}, ptr addrspace(4) null, i64 0, i32 1) to i64) 44 45; PLAIN-X: @g = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64) 46@g = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, {double, double}}, ptr addrspace(4) null, i64 0, i32 1) to i64) 47 48; PLAIN-X: @h = constant i64 ptrtoint (ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i32 1) to i64) 49@h = constant i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i64 1) to i64) 50 51; PLAIN-X: @i = constant i64 ptrtoint (ptr addrspace(2) getelementptr ({ i1, ptr addrspace(2) }, ptr null, i64 0, i32 1) to i64) 52@i = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, double}, ptr addrspace(4) null, i64 0, i32 1) to i64) 53 54; The target-dependent folder should cast GEP indices to integer-sized pointers. 55 56; PLAIN: @M = constant ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 1) 57; PLAIN: @N = constant ptr addrspace(4) getelementptr ({ i64, i64 }, ptr addrspace(4) null, i32 0, i32 1) 58; PLAIN: @O = constant ptr addrspace(4) getelementptr ([2 x i64], ptr addrspace(4) null, i32 0, i32 1) 59 60@M = constant ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 1) 61@N = constant ptr addrspace(4) getelementptr ({ i64, i64 }, ptr addrspace(4) null, i32 0, i32 1) 62@O = constant ptr addrspace(4) getelementptr ([2 x i64], ptr addrspace(4) null, i32 0, i32 1) 63 64; Fold GEP of a GEP. Very simple cases are folded. 65 66; PLAIN-X: @Y = global ptraddrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptraddrspace(3) @ext, i64 2) 67@ext = external addrspace(3) global [3 x { i32, i32 }] 68@Y = global ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) @ext, i64 1), i64 1) 69 70; PLAIN-X: @Z = global ptraddrspace(3) getelementptr inbounds (i32, ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) @ext, i64 0, i64 1, i32 0), i64 1) 71@Z = global ptr addrspace(3) getelementptr inbounds (i32, ptr addrspace(3) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(3) @ext, i64 0, i64 1, i32 0), i64 1) 72 73 74; Duplicate all of the above as function return values rather than 75; global initializers. 76 77; PLAIN: define ptr addrspace(1) @goo8() #0 { 78; PLAIN: %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) to ptr addrspace(1) 79; PLAIN: ret ptr addrspace(1) %t 80; PLAIN: } 81; PLAIN: define ptr addrspace(2) @goo1() #0 { 82; PLAIN: %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -1) to ptr addrspace(2) 83; PLAIN: ret ptr addrspace(2) %t 84; PLAIN: } 85; PLAIN: define ptr addrspace(1) @foo8() #0 { 86; PLAIN: %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) to ptr addrspace(1) 87; PLAIN: ret ptr addrspace(1) %t 88; PLAIN: } 89; PLAIN: define ptr addrspace(2) @foo1() #0 { 90; PLAIN: %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -2) to ptr addrspace(2) 91; PLAIN: ret ptr addrspace(2) %t 92; PLAIN: } 93; PLAIN: define ptr addrspace(1) @hoo8() #0 { 94; PLAIN: %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i32 -1) to ptr addrspace(1) 95; PLAIN: ret ptr addrspace(1) %t 96; PLAIN: } 97; PLAIN: define ptr addrspace(2) @hoo1() #0 { 98; PLAIN: %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i32 -1) to ptr addrspace(2) 99; PLAIN: ret ptr addrspace(2) %t 100; PLAIN: } 101define ptr addrspace(1) @goo8() #0 { 102 %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -1) to ptr addrspace(1) 103 ret ptr addrspace(1) %t 104} 105define ptr addrspace(2) @goo1() #0 { 106 %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -1) to ptr addrspace(2) 107 ret ptr addrspace(2) %t 108} 109define ptr addrspace(1) @foo8() #0 { 110 %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 1 to ptr addrspace(1)), i32 -2) to ptr addrspace(1) 111 ret ptr addrspace(1) %t 112} 113define ptr addrspace(2) @foo1() #0 { 114 %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 1 to ptr addrspace(2)), i32 -2) to ptr addrspace(2) 115 ret ptr addrspace(2) %t 116} 117define ptr addrspace(1) @hoo8() #0 { 118 %t = bitcast ptr addrspace(1) getelementptr (i8, ptr addrspace(1) inttoptr (i32 0 to ptr addrspace(1)), i32 -1) to ptr addrspace(1) 119 ret ptr addrspace(1) %t 120} 121define ptr addrspace(2) @hoo1() #0 { 122 %t = bitcast ptr addrspace(2) getelementptr (i1, ptr addrspace(2) inttoptr (i32 0 to ptr addrspace(2)), i32 -1) to ptr addrspace(2) 123 ret ptr addrspace(2) %t 124} 125 126; PLAIN-X: define i64 @fa() #0 { 127; PLAIN-X: %t = bitcast i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2310) to i64 128; PLAIN-X: ret i64 %t 129; PLAIN-X: } 130; PLAIN-X: define i64 @fb() #0 { 131; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64) to i64 132; PLAIN-X: ret i64 %t 133; PLAIN-X: } 134; PLAIN-X: define i64 @fc() #0 { 135; PLAIN-X: %t = bitcast i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2) to i64 136; PLAIN-X: ret i64 %t 137; PLAIN-X: } 138; PLAIN-X: define i64 @fd() #0 { 139; PLAIN-X: %t = bitcast i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 11) to i64 140; PLAIN-X: ret i64 %t 141; PLAIN-X: } 142; PLAIN-X: define i64 @fe() #0 { 143; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64) to i64 144; PLAIN-X: ret i64 %t 145; PLAIN-X: } 146; PLAIN-X: define i64 @ff() #0 { 147; PLAIN-X: %t = bitcast i64 1 to i64 148; PLAIN-X: ret i64 %t 149; PLAIN-X: } 150; PLAIN-X: define i64 @fg() #0 { 151; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64) to i64 152; PLAIN-X: ret i64 %t 153; PLAIN-X: } 154; PLAIN-X: define i64 @fh() #0 { 155; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(2) getelementptr (i1, ptr addrspace(2) null, i32 1) to i64) to i64 156; PLAIN-X: ret i64 %t 157; PLAIN-X: } 158; PLAIN-X: define i64 @fi() #0 { 159; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(2) getelementptr ({ i1, ptr addrspace(2) }, ptr null, i64 0, i32 1) to i64) to i64 160; PLAIN-X: ret i64 %t 161; PLAIN-X: } 162define i64 @fa() #0 { 163 %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 164 ret i64 %t 165} 166define i64 @fb() #0 { 167 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64 168 ret i64 %t 169} 170define i64 @fc() #0 { 171 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({double, double, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) to i64 172 ret i64 %t 173} 174define i64 @fd() #0 { 175 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ([13 x double], ptr addrspace(4) null, i64 0, i32 11) to i64) to i64 176 ret i64 %t 177} 178define i64 @fe() #0 { 179 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({double, float, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64) to i64 180 ret i64 %t 181} 182define i64 @ff() #0 { 183 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, <{ i16, i128 }>}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64 184 ret i64 %t 185} 186define i64 @fg() #0 { 187 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, {double, double}}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64 188 ret i64 %t 189} 190define i64 @fh() #0 { 191 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64) to i64 192 ret i64 %t 193} 194define i64 @fi() #0 { 195 %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, double}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64 196 ret i64 %t 197} 198 199; PLAIN: define ptr @fM() #0 { 200; PLAIN: %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr 201; PLAIN: ret ptr %t 202; PLAIN: } 203; PLAIN: define ptr @fN() #0 { 204; PLAIN: %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr 205; PLAIN: ret ptr %t 206; PLAIN: } 207; PLAIN: define ptr @fO() #0 { 208; PLAIN: %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr 209; PLAIN: ret ptr %t 210; PLAIN: } 211 212define ptr @fM() #0 { 213 %t = bitcast ptr getelementptr (i64, ptr null, i32 1) to ptr 214 ret ptr %t 215} 216define ptr @fN() #0 { 217 %t = bitcast ptr getelementptr ({ i64, i64 }, ptr null, i32 0, i32 1) to ptr 218 ret ptr %t 219} 220define ptr @fO() #0 { 221 %t = bitcast ptr getelementptr ([2 x i64], ptr null, i32 0, i32 1) to ptr 222 ret ptr %t 223} 224 225; PLAIN: define ptr addrspace(1) @fZ() #0 { 226; PLAIN: %t = bitcast ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(1) @ext2, i64 0, i64 1, i32 0), i64 1) to ptr addrspace(1) 227; PLAIN: ret ptr addrspace(1) %t 228; PLAIN: } 229@ext2 = external addrspace(1) global [3 x { i32, i32 }] 230define ptr addrspace(1) @fZ() #0 { 231 %t = bitcast ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) getelementptr inbounds ([3 x { i32, i32 }], ptr addrspace(1) @ext2, i64 0, i64 1, i32 0), i64 1) to ptr addrspace(1) 232 ret ptr addrspace(1) %t 233} 234 235attributes #0 = { nounwind } 236