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 target 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 i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) 11 @G8 = global i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) 12 ; PLAIN: @G1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -1) 13 @G1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -1) 14 ; PLAIN: @F8 = global i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) 15 @F8 = global i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) 16 ; PLAIN: @F1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -2) 17 @F1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i8 1 to i1 addrspace(2)*), i8 -2) 18 ; PLAIN: @H8 = global i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i32 -1) 19 @H8 = global i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 0 to i8 addrspace(1)*), i32 -1) 20 ; PLAIN: @H1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* null, i8 -1) 21 @H1 = global i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i8 0 to i1 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 (double addrspace(4)* getelementptr (double, double addrspace(4)* null, i32 1) to i64), i64 2310) 28 @a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]} addrspace(4)* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]} addrspace(4)* null, i64 11) to i64), i64 5)) 29 30 ; PLAIN-X: @b = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64) 31 @b = constant i64 ptrtoint ([13 x double] addrspace(4)* getelementptr ({i1, [13 x double]}, {i1, [13 x double]} addrspace(4)* null, i64 0, i32 1) to i64) 32 33 ; PLAIN-X: @c = constant i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double, double addrspace(4)* null, i32 1) to i64), i64 2) 34 @c = constant i64 ptrtoint (double addrspace(4)* getelementptr ({double, double, double, double}, {double, double, double, double} addrspace(4)* null, i64 0, i32 2) to i64) 35 36 ; PLAIN-X: @d = constant i64 mul nuw (i64 ptrtoint (double addrspace(4)* getelementptr (double, double addrspace(4)* null, i32 1) to i64), i64 11) 37 @d = constant i64 ptrtoint (double addrspace(4)* getelementptr ([13 x double], [13 x double] addrspace(4)* null, i64 0, i32 11) to i64) 38 39 ; PLAIN-X: @e = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ double, float, double, double }, { double, float, double, double }* null, i64 0, i32 2) to i64) 40 @e = constant i64 ptrtoint (double addrspace(4)* getelementptr ({double, float, double, double}, {double, float, double, double} addrspace(4)* null, i64 0, i32 2) to i64) 41 42 ; PLAIN-X: @f = constant i64 1 43 @f = constant i64 ptrtoint (<{ i16, i128 }> addrspace(4)* getelementptr ({i1, <{ i16, i128 }>}, {i1, <{ i16, i128 }>} addrspace(4)* null, i64 0, i32 1) to i64) 44 45 ; PLAIN-X: @g = constant i64 ptrtoint (double addrspace(4)* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64) 46 @g = constant i64 ptrtoint ({double, double} addrspace(4)* getelementptr ({i1, {double, double}}, {i1, {double, double}} addrspace(4)* null, i64 0, i32 1) to i64) 47 48 ; PLAIN-X: @h = constant i64 ptrtoint (i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* null, i32 1) to i64) 49 @h = constant i64 ptrtoint (double addrspace(4)* getelementptr (double, double addrspace(4)* null, i64 1) to i64) 50 51 ; PLAIN-X: @i = constant i64 ptrtoint (i1 addrspace(2)* getelementptr ({ i1, i1 addrspace(2)* }, { i1, i1 addrspace(2)* }* null, i64 0, i32 1) to i64) 52 @i = constant i64 ptrtoint (double addrspace(4)* getelementptr ({i1, double}, {i1, double} 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 i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 1) 57 ; PLAIN: @N = constant i64 addrspace(4)* getelementptr ({ i64, i64 }, { i64, i64 } addrspace(4)* null, i32 0, i32 1) 58 ; PLAIN: @O = constant i64 addrspace(4)* getelementptr ([2 x i64], [2 x i64] addrspace(4)* null, i32 0, i32 1) 59 60 @M = constant i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 1) 61 @N = constant i64 addrspace(4)* getelementptr ({ i64, i64 }, { i64, i64 } addrspace(4)* null, i32 0, i32 1) 62 @O = constant i64 addrspace(4)* getelementptr ([2 x i64], [2 x i64] 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 [3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]addrspace(3)* @ext, i64 2) 67 @ext = external addrspace(3) global [3 x { i32, i32 }] 68 @Y = global [3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]addrspace(3)* @ext, i64 1), i64 1) 69 70 ; PLAIN-X: @Z = global i32addrspace(3)* getelementptr inbounds (i32, i32addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]addrspace(3)* @ext, i64 0, i64 1, i32 0), i64 1) 71 @Z = global i32addrspace(3)* getelementptr inbounds (i32, i32addrspace(3)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]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 i8 addrspace(1)* @goo8() #0 { 78 ; PLAIN: %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)* 79 ; PLAIN: ret i8 addrspace(1)* %t 80 ; PLAIN: } 81 ; PLAIN: define i1 addrspace(2)* @goo1() #0 { 82 ; PLAIN: %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)* 83 ; PLAIN: ret i1 addrspace(2)* %t 84 ; PLAIN: } 85 ; PLAIN: define i8 addrspace(1)* @foo8() #0 { 86 ; PLAIN: %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) to i8 addrspace(1)* 87 ; PLAIN: ret i8 addrspace(1)* %t 88 ; PLAIN: } 89 ; PLAIN: define i1 addrspace(2)* @foo1() #0 { 90 ; PLAIN: %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -2) to i1 addrspace(2)* 91 ; PLAIN: ret i1 addrspace(2)* %t 92 ; PLAIN: } 93 ; PLAIN: define i8 addrspace(1)* @hoo8() #0 { 94 ; PLAIN: %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i32 -1) to i8 addrspace(1)* 95 ; PLAIN: ret i8 addrspace(1)* %t 96 ; PLAIN: } 97 ; PLAIN: define i1 addrspace(2)* @hoo1() #0 { 98 ; PLAIN: %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* null, i32 -1) to i1 addrspace(2)* 99 ; PLAIN: ret i1 addrspace(2)* %t 100 ; PLAIN: } 101 define i8 addrspace(1)* @goo8() #0 { 102 %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)* 103 ret i8 addrspace(1)* %t 104 } 105 define i1 addrspace(2)* @goo1() #0 { 106 %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)* 107 ret i1 addrspace(2)* %t 108 } 109 define i8 addrspace(1)* @foo8() #0 { 110 %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 1 to i8 addrspace(1)*), i32 -2) to i8 addrspace(1)* 111 ret i8 addrspace(1)* %t 112 } 113 define i1 addrspace(2)* @foo1() #0 { 114 %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i32 1 to i1 addrspace(2)*), i32 -2) to i1 addrspace(2)* 115 ret i1 addrspace(2)* %t 116 } 117 define i8 addrspace(1)* @hoo8() #0 { 118 %t = bitcast i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* inttoptr (i32 0 to i8 addrspace(1)*), i32 -1) to i8 addrspace(1)* 119 ret i8 addrspace(1)* %t 120 } 121 define i1 addrspace(2)* @hoo1() #0 { 122 %t = bitcast i1 addrspace(2)* getelementptr (i1, i1 addrspace(2)* inttoptr (i32 0 to i1 addrspace(2)*), i32 -1) to i1 addrspace(2)* 123 ret i1 addrspace(2)* %t 124 } 125 126 ; PLAIN-X: define i64 @fa() #0 { 127 ; PLAIN-X: %t = bitcast i64 mul (i64 ptrtoint (double addrspace(4)* getelementptr (double, double 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 (double addrspace(4)* getelementptr ({ i1, double }, { i1, double }* 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 (double addrspace(4)* getelementptr (double, double 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 (double addrspace(4)* getelementptr (double, double 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 (double addrspace(4)* getelementptr ({ double, float, double, double }, { double, float, double, double }* 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 (double addrspace(4)* getelementptr ({ i1, double }, { i1, double }* 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 (i1 addrspace(2)* getelementptr (i1, i1 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 (i1 addrspace(2)* getelementptr ({ i1, i1 addrspace(2)* }, { i1, i1 addrspace(2)* }* null, i64 0, i32 1) to i64) to i64 160 ; PLAIN-X: ret i64 %t 161 ; PLAIN-X: } 162 define i64 @fa() #0 { 163 %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64 164 ret i64 %t 165 } 166 define i64 @fb() #0 { 167 %t = bitcast i64 ptrtoint ([13 x double] addrspace(4)* getelementptr ({i1, [13 x double]}, {i1, [13 x double]} addrspace(4)* null, i64 0, i32 1) to i64) to i64 168 ret i64 %t 169 } 170 define i64 @fc() #0 { 171 %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({double, double, double, double}, {double, double, double, double} addrspace(4)* null, i64 0, i32 2) to i64) to i64 172 ret i64 %t 173 } 174 define i64 @fd() #0 { 175 %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ([13 x double], [13 x double] addrspace(4)* null, i64 0, i32 11) to i64) to i64 176 ret i64 %t 177 } 178 define i64 @fe() #0 { 179 %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({double, float, double, double}, {double, float, double, double} addrspace(4)* null, i64 0, i32 2) to i64) to i64 180 ret i64 %t 181 } 182 define i64 @ff() #0 { 183 %t = bitcast i64 ptrtoint (<{ i16, i128 }> addrspace(4)* getelementptr ({i1, <{ i16, i128 }>}, {i1, <{ i16, i128 }>} addrspace(4)* null, i64 0, i32 1) to i64) to i64 184 ret i64 %t 185 } 186 define i64 @fg() #0 { 187 %t = bitcast i64 ptrtoint ({double, double} addrspace(4)* getelementptr ({i1, {double, double}}, {i1, {double, double}} addrspace(4)* null, i64 0, i32 1) to i64) to i64 188 ret i64 %t 189 } 190 define i64 @fh() #0 { 191 %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr (double, double addrspace(4)* null, i32 1) to i64) to i64 192 ret i64 %t 193 } 194 define i64 @fi() #0 { 195 %t = bitcast i64 ptrtoint (double addrspace(4)* getelementptr ({i1, double}, {i1, double}addrspace(4)* null, i64 0, i32 1) to i64) to i64 196 ret i64 %t 197 } 198 199 ; PLAIN: define i64* @fM() #0 { 200 ; PLAIN: %t = bitcast i64* getelementptr (i64, i64* null, i32 1) to i64* 201 ; PLAIN: ret i64* %t 202 ; PLAIN: } 203 ; PLAIN: define i64* @fN() #0 { 204 ; PLAIN: %t = bitcast i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1) to i64* 205 ; PLAIN: ret i64* %t 206 ; PLAIN: } 207 ; PLAIN: define i64* @fO() #0 { 208 ; PLAIN: %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64* 209 ; PLAIN: ret i64* %t 210 ; PLAIN: } 211 212 define i64* @fM() #0 { 213 %t = bitcast i64* getelementptr (i64, i64* null, i32 1) to i64* 214 ret i64* %t 215 } 216 define i64* @fN() #0 { 217 %t = bitcast i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1) to i64* 218 ret i64* %t 219 } 220 define i64* @fO() #0 { 221 %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64* 222 ret i64* %t 223 } 224 225 ; PLAIN: define i32 addrspace(1)* @fZ() #0 { 226 ; PLAIN: %t = bitcast i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }] addrspace(1)* @ext2, i64 0, i64 1, i32 0), i64 1) to i32 addrspace(1)* 227 ; PLAIN: ret i32 addrspace(1)* %t 228 ; PLAIN: } 229 @ext2 = external addrspace(1) global [3 x { i32, i32 }] 230 define i32 addrspace(1)* @fZ() #0 { 231 %t = bitcast i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }] addrspace(1)* @ext2, i64 0, i64 1, i32 0), i64 1) to i32 addrspace(1)* 232 ret i32 addrspace(1)* %t 233 } 234 235 attributes #0 = { nounwind } 236