1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm64-unknown | FileCheck %s 3 4; i8* p; // p is 1 byte aligned 5; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24) 6define i32 @load_i32_by_i8_unaligned(i32* %arg) { 7; CHECK-LABEL: load_i32_by_i8_unaligned: 8; CHECK: // %bb.0: 9; CHECK-NEXT: ldr w0, [x0] 10; CHECK-NEXT: ret 11 %tmp = bitcast i32* %arg to i8* 12 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 13 %tmp2 = load i8, i8* %tmp1, align 1 14 %tmp3 = zext i8 %tmp2 to i32 15 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 16 %tmp5 = load i8, i8* %tmp4, align 1 17 %tmp6 = zext i8 %tmp5 to i32 18 %tmp7 = shl nuw nsw i32 %tmp6, 8 19 %tmp8 = or i32 %tmp7, %tmp3 20 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 2 21 %tmp10 = load i8, i8* %tmp9, align 1 22 %tmp11 = zext i8 %tmp10 to i32 23 %tmp12 = shl nuw nsw i32 %tmp11, 16 24 %tmp13 = or i32 %tmp8, %tmp12 25 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 3 26 %tmp15 = load i8, i8* %tmp14, align 1 27 %tmp16 = zext i8 %tmp15 to i32 28 %tmp17 = shl nuw nsw i32 %tmp16, 24 29 %tmp18 = or i32 %tmp13, %tmp17 30 ret i32 %tmp18 31} 32 33; i8* p; // p is 4 byte aligned 34; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24) 35define i32 @load_i32_by_i8_aligned(i32* %arg) { 36; CHECK-LABEL: load_i32_by_i8_aligned: 37; CHECK: // %bb.0: 38; CHECK-NEXT: ldr w0, [x0] 39; CHECK-NEXT: ret 40 %tmp = bitcast i32* %arg to i8* 41 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 42 %tmp2 = load i8, i8* %tmp1, align 4 43 %tmp3 = zext i8 %tmp2 to i32 44 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 45 %tmp5 = load i8, i8* %tmp4, align 1 46 %tmp6 = zext i8 %tmp5 to i32 47 %tmp7 = shl nuw nsw i32 %tmp6, 8 48 %tmp8 = or i32 %tmp7, %tmp3 49 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 2 50 %tmp10 = load i8, i8* %tmp9, align 1 51 %tmp11 = zext i8 %tmp10 to i32 52 %tmp12 = shl nuw nsw i32 %tmp11, 16 53 %tmp13 = or i32 %tmp8, %tmp12 54 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 3 55 %tmp15 = load i8, i8* %tmp14, align 1 56 %tmp16 = zext i8 %tmp15 to i32 57 %tmp17 = shl nuw nsw i32 %tmp16, 24 58 %tmp18 = or i32 %tmp13, %tmp17 59 ret i32 %tmp18 60} 61 62; i8* p; // p is 4 byte aligned 63; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3] 64define i32 @load_i32_by_i8_bswap(i32* %arg) { 65; CHECK-LABEL: load_i32_by_i8_bswap: 66; CHECK: // %bb.0: 67; CHECK-NEXT: ldr w8, [x0] 68; CHECK-NEXT: rev w0, w8 69; CHECK-NEXT: ret 70 %tmp = bitcast i32* %arg to i8* 71 %tmp1 = load i8, i8* %tmp, align 4 72 %tmp2 = zext i8 %tmp1 to i32 73 %tmp3 = shl nuw nsw i32 %tmp2, 24 74 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 75 %tmp5 = load i8, i8* %tmp4, align 1 76 %tmp6 = zext i8 %tmp5 to i32 77 %tmp7 = shl nuw nsw i32 %tmp6, 16 78 %tmp8 = or i32 %tmp7, %tmp3 79 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 2 80 %tmp10 = load i8, i8* %tmp9, align 1 81 %tmp11 = zext i8 %tmp10 to i32 82 %tmp12 = shl nuw nsw i32 %tmp11, 8 83 %tmp13 = or i32 %tmp8, %tmp12 84 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 3 85 %tmp15 = load i8, i8* %tmp14, align 1 86 %tmp16 = zext i8 %tmp15 to i32 87 %tmp17 = or i32 %tmp13, %tmp16 88 ret i32 %tmp17 89} 90 91; i8* p; // p is 8 byte aligned 92; (i64) p[0] | ((i64) p[1] << 8) | ((i64) p[2] << 16) | ((i64) p[3] << 24) | ((i64) p[4] << 32) | ((i64) p[5] << 40) | ((i64) p[6] << 48) | ((i64) p[7] << 56) 93define i64 @load_i64_by_i8(i64* %arg) { 94; CHECK-LABEL: load_i64_by_i8: 95; CHECK: // %bb.0: 96; CHECK-NEXT: ldr x0, [x0] 97; CHECK-NEXT: ret 98 %tmp = bitcast i64* %arg to i8* 99 %tmp1 = load i8, i8* %tmp, align 8 100 %tmp2 = zext i8 %tmp1 to i64 101 %tmp3 = getelementptr inbounds i8, i8* %tmp, i64 1 102 %tmp4 = load i8, i8* %tmp3, align 1 103 %tmp5 = zext i8 %tmp4 to i64 104 %tmp6 = shl nuw nsw i64 %tmp5, 8 105 %tmp7 = or i64 %tmp6, %tmp2 106 %tmp8 = getelementptr inbounds i8, i8* %tmp, i64 2 107 %tmp9 = load i8, i8* %tmp8, align 1 108 %tmp10 = zext i8 %tmp9 to i64 109 %tmp11 = shl nuw nsw i64 %tmp10, 16 110 %tmp12 = or i64 %tmp7, %tmp11 111 %tmp13 = getelementptr inbounds i8, i8* %tmp, i64 3 112 %tmp14 = load i8, i8* %tmp13, align 1 113 %tmp15 = zext i8 %tmp14 to i64 114 %tmp16 = shl nuw nsw i64 %tmp15, 24 115 %tmp17 = or i64 %tmp12, %tmp16 116 %tmp18 = getelementptr inbounds i8, i8* %tmp, i64 4 117 %tmp19 = load i8, i8* %tmp18, align 1 118 %tmp20 = zext i8 %tmp19 to i64 119 %tmp21 = shl nuw nsw i64 %tmp20, 32 120 %tmp22 = or i64 %tmp17, %tmp21 121 %tmp23 = getelementptr inbounds i8, i8* %tmp, i64 5 122 %tmp24 = load i8, i8* %tmp23, align 1 123 %tmp25 = zext i8 %tmp24 to i64 124 %tmp26 = shl nuw nsw i64 %tmp25, 40 125 %tmp27 = or i64 %tmp22, %tmp26 126 %tmp28 = getelementptr inbounds i8, i8* %tmp, i64 6 127 %tmp29 = load i8, i8* %tmp28, align 1 128 %tmp30 = zext i8 %tmp29 to i64 129 %tmp31 = shl nuw nsw i64 %tmp30, 48 130 %tmp32 = or i64 %tmp27, %tmp31 131 %tmp33 = getelementptr inbounds i8, i8* %tmp, i64 7 132 %tmp34 = load i8, i8* %tmp33, align 1 133 %tmp35 = zext i8 %tmp34 to i64 134 %tmp36 = shl nuw i64 %tmp35, 56 135 %tmp37 = or i64 %tmp32, %tmp36 136 ret i64 %tmp37 137} 138 139; i8* p; // p is 8 byte aligned 140; ((i64) p[0] << 56) | ((i64) p[1] << 48) | ((i64) p[2] << 40) | ((i64) p[3] << 32) | ((i64) p[4] << 24) | ((i64) p[5] << 16) | ((i64) p[6] << 8) | (i64) p[7] 141define i64 @load_i64_by_i8_bswap(i64* %arg) { 142; CHECK-LABEL: load_i64_by_i8_bswap: 143; CHECK: // %bb.0: 144; CHECK-NEXT: ldr x8, [x0] 145; CHECK-NEXT: rev x0, x8 146; CHECK-NEXT: ret 147 %tmp = bitcast i64* %arg to i8* 148 %tmp1 = load i8, i8* %tmp, align 8 149 %tmp2 = zext i8 %tmp1 to i64 150 %tmp3 = shl nuw i64 %tmp2, 56 151 %tmp4 = getelementptr inbounds i8, i8* %tmp, i64 1 152 %tmp5 = load i8, i8* %tmp4, align 1 153 %tmp6 = zext i8 %tmp5 to i64 154 %tmp7 = shl nuw nsw i64 %tmp6, 48 155 %tmp8 = or i64 %tmp7, %tmp3 156 %tmp9 = getelementptr inbounds i8, i8* %tmp, i64 2 157 %tmp10 = load i8, i8* %tmp9, align 1 158 %tmp11 = zext i8 %tmp10 to i64 159 %tmp12 = shl nuw nsw i64 %tmp11, 40 160 %tmp13 = or i64 %tmp8, %tmp12 161 %tmp14 = getelementptr inbounds i8, i8* %tmp, i64 3 162 %tmp15 = load i8, i8* %tmp14, align 1 163 %tmp16 = zext i8 %tmp15 to i64 164 %tmp17 = shl nuw nsw i64 %tmp16, 32 165 %tmp18 = or i64 %tmp13, %tmp17 166 %tmp19 = getelementptr inbounds i8, i8* %tmp, i64 4 167 %tmp20 = load i8, i8* %tmp19, align 1 168 %tmp21 = zext i8 %tmp20 to i64 169 %tmp22 = shl nuw nsw i64 %tmp21, 24 170 %tmp23 = or i64 %tmp18, %tmp22 171 %tmp24 = getelementptr inbounds i8, i8* %tmp, i64 5 172 %tmp25 = load i8, i8* %tmp24, align 1 173 %tmp26 = zext i8 %tmp25 to i64 174 %tmp27 = shl nuw nsw i64 %tmp26, 16 175 %tmp28 = or i64 %tmp23, %tmp27 176 %tmp29 = getelementptr inbounds i8, i8* %tmp, i64 6 177 %tmp30 = load i8, i8* %tmp29, align 1 178 %tmp31 = zext i8 %tmp30 to i64 179 %tmp32 = shl nuw nsw i64 %tmp31, 8 180 %tmp33 = or i64 %tmp28, %tmp32 181 %tmp34 = getelementptr inbounds i8, i8* %tmp, i64 7 182 %tmp35 = load i8, i8* %tmp34, align 1 183 %tmp36 = zext i8 %tmp35 to i64 184 %tmp37 = or i64 %tmp33, %tmp36 185 ret i64 %tmp37 186} 187 188; i8* p; // p[1] is 4 byte aligned 189; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24) 190define i32 @load_i32_by_i8_nonzero_offset(i32* %arg) { 191; CHECK-LABEL: load_i32_by_i8_nonzero_offset: 192; CHECK: // %bb.0: 193; CHECK-NEXT: ldur w0, [x0, #1] 194; CHECK-NEXT: ret 195 196 %tmp = bitcast i32* %arg to i8* 197 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 1 198 %tmp2 = load i8, i8* %tmp1, align 4 199 %tmp3 = zext i8 %tmp2 to i32 200 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 2 201 %tmp5 = load i8, i8* %tmp4, align 1 202 %tmp6 = zext i8 %tmp5 to i32 203 %tmp7 = shl nuw nsw i32 %tmp6, 8 204 %tmp8 = or i32 %tmp7, %tmp3 205 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 3 206 %tmp10 = load i8, i8* %tmp9, align 1 207 %tmp11 = zext i8 %tmp10 to i32 208 %tmp12 = shl nuw nsw i32 %tmp11, 16 209 %tmp13 = or i32 %tmp8, %tmp12 210 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 4 211 %tmp15 = load i8, i8* %tmp14, align 1 212 %tmp16 = zext i8 %tmp15 to i32 213 %tmp17 = shl nuw nsw i32 %tmp16, 24 214 %tmp18 = or i32 %tmp13, %tmp17 215 ret i32 %tmp18 216} 217 218; i8* p; // p[-4] is 4 byte aligned 219; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24) 220define i32 @load_i32_by_i8_neg_offset(i32* %arg) { 221; CHECK-LABEL: load_i32_by_i8_neg_offset: 222; CHECK: // %bb.0: 223; CHECK-NEXT: ldur w0, [x0, #-4] 224; CHECK-NEXT: ret 225 226 %tmp = bitcast i32* %arg to i8* 227 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 -4 228 %tmp2 = load i8, i8* %tmp1, align 4 229 %tmp3 = zext i8 %tmp2 to i32 230 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 -3 231 %tmp5 = load i8, i8* %tmp4, align 1 232 %tmp6 = zext i8 %tmp5 to i32 233 %tmp7 = shl nuw nsw i32 %tmp6, 8 234 %tmp8 = or i32 %tmp7, %tmp3 235 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 -2 236 %tmp10 = load i8, i8* %tmp9, align 1 237 %tmp11 = zext i8 %tmp10 to i32 238 %tmp12 = shl nuw nsw i32 %tmp11, 16 239 %tmp13 = or i32 %tmp8, %tmp12 240 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 -1 241 %tmp15 = load i8, i8* %tmp14, align 1 242 %tmp16 = zext i8 %tmp15 to i32 243 %tmp17 = shl nuw nsw i32 %tmp16, 24 244 %tmp18 = or i32 %tmp13, %tmp17 245 ret i32 %tmp18 246} 247 248; i8* p; // p[1] is 4 byte aligned 249; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24) 250define i32 @load_i32_by_i8_nonzero_offset_bswap(i32* %arg) { 251; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap: 252; CHECK: // %bb.0: 253; CHECK-NEXT: ldur w8, [x0, #1] 254; CHECK-NEXT: rev w0, w8 255; CHECK-NEXT: ret 256 257 %tmp = bitcast i32* %arg to i8* 258 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 4 259 %tmp2 = load i8, i8* %tmp1, align 1 260 %tmp3 = zext i8 %tmp2 to i32 261 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 3 262 %tmp5 = load i8, i8* %tmp4, align 1 263 %tmp6 = zext i8 %tmp5 to i32 264 %tmp7 = shl nuw nsw i32 %tmp6, 8 265 %tmp8 = or i32 %tmp7, %tmp3 266 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 2 267 %tmp10 = load i8, i8* %tmp9, align 1 268 %tmp11 = zext i8 %tmp10 to i32 269 %tmp12 = shl nuw nsw i32 %tmp11, 16 270 %tmp13 = or i32 %tmp8, %tmp12 271 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 1 272 %tmp15 = load i8, i8* %tmp14, align 4 273 %tmp16 = zext i8 %tmp15 to i32 274 %tmp17 = shl nuw nsw i32 %tmp16, 24 275 %tmp18 = or i32 %tmp13, %tmp17 276 ret i32 %tmp18 277} 278 279; i8* p; // p[-4] is 4 byte aligned 280; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24) 281define i32 @load_i32_by_i8_neg_offset_bswap(i32* %arg) { 282; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap: 283; CHECK: // %bb.0: 284; CHECK-NEXT: ldur w8, [x0, #-4] 285; CHECK-NEXT: rev w0, w8 286; CHECK-NEXT: ret 287 288 %tmp = bitcast i32* %arg to i8* 289 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 -1 290 %tmp2 = load i8, i8* %tmp1, align 1 291 %tmp3 = zext i8 %tmp2 to i32 292 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 -2 293 %tmp5 = load i8, i8* %tmp4, align 1 294 %tmp6 = zext i8 %tmp5 to i32 295 %tmp7 = shl nuw nsw i32 %tmp6, 8 296 %tmp8 = or i32 %tmp7, %tmp3 297 %tmp9 = getelementptr inbounds i8, i8* %tmp, i32 -3 298 %tmp10 = load i8, i8* %tmp9, align 1 299 %tmp11 = zext i8 %tmp10 to i32 300 %tmp12 = shl nuw nsw i32 %tmp11, 16 301 %tmp13 = or i32 %tmp8, %tmp12 302 %tmp14 = getelementptr inbounds i8, i8* %tmp, i32 -4 303 %tmp15 = load i8, i8* %tmp14, align 4 304 %tmp16 = zext i8 %tmp15 to i32 305 %tmp17 = shl nuw nsw i32 %tmp16, 24 306 %tmp18 = or i32 %tmp13, %tmp17 307 ret i32 %tmp18 308} 309 310declare i16 @llvm.bswap.i16(i16) 311 312; i16* p; // p is 4 byte aligned 313; (i32) bswap(p[1]) | (i32) bswap(p[0] << 16) 314define i32 @load_i32_by_bswap_i16(i32* %arg) { 315; CHECK-LABEL: load_i32_by_bswap_i16: 316; CHECK: // %bb.0: 317; CHECK-NEXT: ldr w8, [x0] 318; CHECK-NEXT: rev w0, w8 319; CHECK-NEXT: ret 320 321 %tmp = bitcast i32* %arg to i16* 322 %tmp1 = load i16, i16* %tmp, align 4 323 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1) 324 %tmp2 = zext i16 %tmp11 to i32 325 %tmp3 = getelementptr inbounds i16, i16* %tmp, i32 1 326 %tmp4 = load i16, i16* %tmp3, align 1 327 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4) 328 %tmp5 = zext i16 %tmp41 to i32 329 %tmp6 = shl nuw nsw i32 %tmp2, 16 330 %tmp7 = or i32 %tmp6, %tmp5 331 ret i32 %tmp7 332} 333 334; i16* p; // p is 4 byte aligned 335; (i32) p[0] | (sext(p[1] << 16) to i32) 336define i32 @load_i32_by_sext_i16(i32* %arg) { 337; CHECK-LABEL: load_i32_by_sext_i16: 338; CHECK: // %bb.0: 339; CHECK-NEXT: ldr w0, [x0] 340; CHECK-NEXT: ret 341 %tmp = bitcast i32* %arg to i16* 342 %tmp1 = load i16, i16* %tmp, align 4 343 %tmp2 = zext i16 %tmp1 to i32 344 %tmp3 = getelementptr inbounds i16, i16* %tmp, i32 1 345 %tmp4 = load i16, i16* %tmp3, align 1 346 %tmp5 = sext i16 %tmp4 to i32 347 %tmp6 = shl nuw nsw i32 %tmp5, 16 348 %tmp7 = or i32 %tmp6, %tmp2 349 ret i32 %tmp7 350} 351 352; i8* arg; i32 i; 353; p = arg + 12; 354; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24) 355define i32 @load_i32_by_i8_base_offset_index(i8* %arg, i32 %i) { 356; CHECK-LABEL: load_i32_by_i8_base_offset_index: 357; CHECK: // %bb.0: 358; CHECK-NEXT: add x8, x0, w1, uxtw 359; CHECK-NEXT: ldr w0, [x8, #12] 360; CHECK-NEXT: ret 361 %tmp = add nuw nsw i32 %i, 3 362 %tmp2 = add nuw nsw i32 %i, 2 363 %tmp3 = add nuw nsw i32 %i, 1 364 %tmp4 = getelementptr inbounds i8, i8* %arg, i64 12 365 %tmp5 = zext i32 %i to i64 366 %tmp6 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp5 367 %tmp7 = load i8, i8* %tmp6, align 4 368 %tmp8 = zext i8 %tmp7 to i32 369 %tmp9 = zext i32 %tmp3 to i64 370 %tmp10 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp9 371 %tmp11 = load i8, i8* %tmp10, align 1 372 %tmp12 = zext i8 %tmp11 to i32 373 %tmp13 = shl nuw nsw i32 %tmp12, 8 374 %tmp14 = or i32 %tmp13, %tmp8 375 %tmp15 = zext i32 %tmp2 to i64 376 %tmp16 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp15 377 %tmp17 = load i8, i8* %tmp16, align 1 378 %tmp18 = zext i8 %tmp17 to i32 379 %tmp19 = shl nuw nsw i32 %tmp18, 16 380 %tmp20 = or i32 %tmp14, %tmp19 381 %tmp21 = zext i32 %tmp to i64 382 %tmp22 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp21 383 %tmp23 = load i8, i8* %tmp22, align 1 384 %tmp24 = zext i8 %tmp23 to i32 385 %tmp25 = shl nuw i32 %tmp24, 24 386 %tmp26 = or i32 %tmp20, %tmp25 387 ret i32 %tmp26 388} 389 390; i8* arg; i32 i; 391; p = arg + 12; 392; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24) 393define i32 @load_i32_by_i8_base_offset_index_2(i8* %arg, i32 %i) { 394; CHECK-LABEL: load_i32_by_i8_base_offset_index_2: 395; CHECK: // %bb.0: 396; CHECK-NEXT: add x8, x0, w1, uxtw 397; CHECK-NEXT: ldur w0, [x8, #13] 398; CHECK-NEXT: ret 399 %tmp = add nuw nsw i32 %i, 4 400 %tmp2 = add nuw nsw i32 %i, 3 401 %tmp3 = add nuw nsw i32 %i, 2 402 %tmp4 = getelementptr inbounds i8, i8* %arg, i64 12 403 %tmp5 = add nuw nsw i32 %i, 1 404 %tmp27 = zext i32 %tmp5 to i64 405 %tmp28 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp27 406 %tmp29 = load i8, i8* %tmp28, align 4 407 %tmp30 = zext i8 %tmp29 to i32 408 %tmp31 = zext i32 %tmp3 to i64 409 %tmp32 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp31 410 %tmp33 = load i8, i8* %tmp32, align 1 411 %tmp34 = zext i8 %tmp33 to i32 412 %tmp35 = shl nuw nsw i32 %tmp34, 8 413 %tmp36 = or i32 %tmp35, %tmp30 414 %tmp37 = zext i32 %tmp2 to i64 415 %tmp38 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp37 416 %tmp39 = load i8, i8* %tmp38, align 1 417 %tmp40 = zext i8 %tmp39 to i32 418 %tmp41 = shl nuw nsw i32 %tmp40, 16 419 %tmp42 = or i32 %tmp36, %tmp41 420 %tmp43 = zext i32 %tmp to i64 421 %tmp44 = getelementptr inbounds i8, i8* %tmp4, i64 %tmp43 422 %tmp45 = load i8, i8* %tmp44, align 1 423 %tmp46 = zext i8 %tmp45 to i32 424 %tmp47 = shl nuw i32 %tmp46, 24 425 %tmp48 = or i32 %tmp42, %tmp47 426 ret i32 %tmp48 427} 428 429; i8* p; // p is 2 byte aligned 430; (i32) p[0] | ((i32) p[1] << 8) 431define i32 @zext_load_i32_by_i8(i32* %arg) { 432; CHECK-LABEL: zext_load_i32_by_i8: 433; CHECK: // %bb.0: 434; CHECK-NEXT: ldrh w0, [x0] 435; CHECK-NEXT: ret 436 437 %tmp = bitcast i32* %arg to i8* 438 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 439 %tmp2 = load i8, i8* %tmp1, align 2 440 %tmp3 = zext i8 %tmp2 to i32 441 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 442 %tmp5 = load i8, i8* %tmp4, align 1 443 %tmp6 = zext i8 %tmp5 to i32 444 %tmp7 = shl nuw nsw i32 %tmp6, 8 445 %tmp8 = or i32 %tmp7, %tmp3 446 ret i32 %tmp8 447} 448 449; i8* p; // p is 2 byte aligned 450; ((i32) p[0] << 8) | ((i32) p[1] << 16) 451define i32 @zext_load_i32_by_i8_shl_8(i32* %arg) { 452; CHECK-LABEL: zext_load_i32_by_i8_shl_8: 453; CHECK: // %bb.0: 454; CHECK-NEXT: ldrb w8, [x0] 455; CHECK-NEXT: ldrb w9, [x0, #1] 456; CHECK-NEXT: lsl w0, w8, #8 457; CHECK-NEXT: bfi w0, w9, #16, #8 458; CHECK-NEXT: ret 459 460 %tmp = bitcast i32* %arg to i8* 461 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 462 %tmp2 = load i8, i8* %tmp1, align 2 463 %tmp3 = zext i8 %tmp2 to i32 464 %tmp30 = shl nuw nsw i32 %tmp3, 8 465 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 466 %tmp5 = load i8, i8* %tmp4, align 1 467 %tmp6 = zext i8 %tmp5 to i32 468 %tmp7 = shl nuw nsw i32 %tmp6, 16 469 %tmp8 = or i32 %tmp7, %tmp30 470 ret i32 %tmp8 471} 472 473; i8* p; // p is 2 byte aligned 474; ((i32) p[0] << 16) | ((i32) p[1] << 24) 475define i32 @zext_load_i32_by_i8_shl_16(i32* %arg) { 476; CHECK-LABEL: zext_load_i32_by_i8_shl_16: 477; CHECK: // %bb.0: 478; CHECK-NEXT: ldrb w8, [x0] 479; CHECK-NEXT: ldrb w9, [x0, #1] 480; CHECK-NEXT: lsl w0, w8, #16 481; CHECK-NEXT: bfi w0, w9, #24, #8 482; CHECK-NEXT: ret 483 484 %tmp = bitcast i32* %arg to i8* 485 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 486 %tmp2 = load i8, i8* %tmp1, align 2 487 %tmp3 = zext i8 %tmp2 to i32 488 %tmp30 = shl nuw nsw i32 %tmp3, 16 489 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 1 490 %tmp5 = load i8, i8* %tmp4, align 1 491 %tmp6 = zext i8 %tmp5 to i32 492 %tmp7 = shl nuw nsw i32 %tmp6, 24 493 %tmp8 = or i32 %tmp7, %tmp30 494 ret i32 %tmp8 495} 496; i8* p; // p is 2 byte aligned 497; (i32) p[1] | ((i32) p[0] << 8) 498define i32 @zext_load_i32_by_i8_bswap(i32* %arg) { 499; CHECK-LABEL: zext_load_i32_by_i8_bswap: 500; CHECK: // %bb.0: 501; CHECK-NEXT: ldrh w8, [x0] 502; CHECK-NEXT: lsl w8, w8, #16 503; CHECK-NEXT: rev w0, w8 504; CHECK-NEXT: ret 505 506 %tmp = bitcast i32* %arg to i8* 507 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 1 508 %tmp2 = load i8, i8* %tmp1, align 1 509 %tmp3 = zext i8 %tmp2 to i32 510 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 0 511 %tmp5 = load i8, i8* %tmp4, align 2 512 %tmp6 = zext i8 %tmp5 to i32 513 %tmp7 = shl nuw nsw i32 %tmp6, 8 514 %tmp8 = or i32 %tmp7, %tmp3 515 ret i32 %tmp8 516} 517 518; i8* p; // p is 2 byte aligned 519; ((i32) p[1] << 8) | ((i32) p[0] << 16) 520define i32 @zext_load_i32_by_i8_bswap_shl_8(i32* %arg) { 521; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8: 522; CHECK: // %bb.0: 523; CHECK-NEXT: ldrb w8, [x0, #1] 524; CHECK-NEXT: ldrb w9, [x0] 525; CHECK-NEXT: lsl w0, w8, #8 526; CHECK-NEXT: bfi w0, w9, #16, #8 527; CHECK-NEXT: ret 528 529 %tmp = bitcast i32* %arg to i8* 530 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 1 531 %tmp2 = load i8, i8* %tmp1, align 1 532 %tmp3 = zext i8 %tmp2 to i32 533 %tmp30 = shl nuw nsw i32 %tmp3, 8 534 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 0 535 %tmp5 = load i8, i8* %tmp4, align 2 536 %tmp6 = zext i8 %tmp5 to i32 537 %tmp7 = shl nuw nsw i32 %tmp6, 16 538 %tmp8 = or i32 %tmp7, %tmp30 539 ret i32 %tmp8 540} 541 542; i8* p; // p is 2 byte aligned 543; ((i32) p[1] << 16) | ((i32) p[0] << 24) 544define i32 @zext_load_i32_by_i8_bswap_shl_16(i32* %arg) { 545; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16: 546; CHECK: // %bb.0: 547; CHECK-NEXT: ldrb w8, [x0, #1] 548; CHECK-NEXT: ldrb w9, [x0] 549; CHECK-NEXT: lsl w0, w8, #16 550; CHECK-NEXT: bfi w0, w9, #24, #8 551; CHECK-NEXT: ret 552 553 %tmp = bitcast i32* %arg to i8* 554 %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 1 555 %tmp2 = load i8, i8* %tmp1, align 1 556 %tmp3 = zext i8 %tmp2 to i32 557 %tmp30 = shl nuw nsw i32 %tmp3, 16 558 %tmp4 = getelementptr inbounds i8, i8* %tmp, i32 0 559 %tmp5 = load i8, i8* %tmp4, align 2 560 %tmp6 = zext i8 %tmp5 to i32 561 %tmp7 = shl nuw nsw i32 %tmp6, 24 562 %tmp8 = or i32 %tmp7, %tmp30 563 ret i32 %tmp8 564} 565