1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx | FileCheck %s 3 4%structTy = type { i8, i32, i32 } 5 6@e = common global %structTy zeroinitializer, align 4 7 8;; Ensure that MergeConsecutiveStores doesn't incorrectly reorder 9;; store operations. The first test stores in increasing address 10;; order, the second in decreasing -- but in both cases should have 11;; the same result in memory in the end. 12 13define void @redundant_stores_merging() { 14; CHECK-LABEL: redundant_stores_merging: 15; CHECK: # %bb.0: 16; CHECK-NEXT: movabsq $1958505086977, %rax # imm = 0x1C800000001 17; CHECK-NEXT: movq %rax, e+{{.*}}(%rip) 18; CHECK-NEXT: retq 19 store i32 1, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 1), align 4 20 store i32 123, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 2), align 4 21 store i32 456, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 2), align 4 22 ret void 23} 24 25;; This variant tests PR25154. 26define void @redundant_stores_merging_reverse() { 27; CHECK-LABEL: redundant_stores_merging_reverse: 28; CHECK: # %bb.0: 29; CHECK-NEXT: movabsq $528280977409, %rax # imm = 0x7B00000001 30; CHECK-NEXT: movq %rax, e+{{.*}}(%rip) 31; CHECK-NEXT: movl $456, e+{{.*}}(%rip) # imm = 0x1C8 32; CHECK-NEXT: retq 33 store i32 123, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 2), align 4 34 store i32 456, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 2), align 4 35 store i32 1, i32* getelementptr inbounds (%structTy, %structTy* @e, i64 0, i32 1), align 4 36 ret void 37} 38 39@b = common global [8 x i8] zeroinitializer, align 2 40 41;; The 2-byte store to offset 3 overlaps the 2-byte store to offset 2; 42;; these must not be reordered in MergeConsecutiveStores such that the 43;; store to 3 comes first (e.g. by merging the stores to 0 and 2 into 44;; a movl, after the store to 3). 45 46define void @overlapping_stores_merging() { 47; CHECK-LABEL: overlapping_stores_merging: 48; CHECK: # %bb.0: 49; CHECK-NEXT: movl $1, {{.*}}(%rip) 50; CHECK-NEXT: movw $2, b+{{.*}}(%rip) 51; CHECK-NEXT: retq 52 store i16 0, i16* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @b, i64 0, i64 2) to i16*), align 2 53 store i16 2, i16* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @b, i64 0, i64 3) to i16*), align 1 54 store i16 1, i16* bitcast (i8* getelementptr inbounds ([8 x i8], [8 x i8]* @b, i64 0, i64 0) to i16*), align 2 55 ret void 56} 57 58define void @extract_vector_store_16_consecutive_bytes(<2 x i64> %v, i8* %ptr) #0 { 59; CHECK-LABEL: extract_vector_store_16_consecutive_bytes: 60; CHECK: # %bb.0: 61; CHECK-NEXT: vmovups %xmm0, (%rdi) 62; CHECK-NEXT: retq 63 %bc = bitcast <2 x i64> %v to <16 x i8> 64 %ext00 = extractelement <16 x i8> %bc, i32 0 65 %ext01 = extractelement <16 x i8> %bc, i32 1 66 %ext02 = extractelement <16 x i8> %bc, i32 2 67 %ext03 = extractelement <16 x i8> %bc, i32 3 68 %ext04 = extractelement <16 x i8> %bc, i32 4 69 %ext05 = extractelement <16 x i8> %bc, i32 5 70 %ext06 = extractelement <16 x i8> %bc, i32 6 71 %ext07 = extractelement <16 x i8> %bc, i32 7 72 %ext08 = extractelement <16 x i8> %bc, i32 8 73 %ext09 = extractelement <16 x i8> %bc, i32 9 74 %ext10 = extractelement <16 x i8> %bc, i32 10 75 %ext11 = extractelement <16 x i8> %bc, i32 11 76 %ext12 = extractelement <16 x i8> %bc, i32 12 77 %ext13 = extractelement <16 x i8> %bc, i32 13 78 %ext14 = extractelement <16 x i8> %bc, i32 14 79 %ext15 = extractelement <16 x i8> %bc, i32 15 80 %gep00 = getelementptr inbounds i8, i8* %ptr, i64 0 81 %gep01 = getelementptr inbounds i8, i8* %ptr, i64 1 82 %gep02 = getelementptr inbounds i8, i8* %ptr, i64 2 83 %gep03 = getelementptr inbounds i8, i8* %ptr, i64 3 84 %gep04 = getelementptr inbounds i8, i8* %ptr, i64 4 85 %gep05 = getelementptr inbounds i8, i8* %ptr, i64 5 86 %gep06 = getelementptr inbounds i8, i8* %ptr, i64 6 87 %gep07 = getelementptr inbounds i8, i8* %ptr, i64 7 88 %gep08 = getelementptr inbounds i8, i8* %ptr, i64 8 89 %gep09 = getelementptr inbounds i8, i8* %ptr, i64 9 90 %gep10 = getelementptr inbounds i8, i8* %ptr, i64 10 91 %gep11 = getelementptr inbounds i8, i8* %ptr, i64 11 92 %gep12 = getelementptr inbounds i8, i8* %ptr, i64 12 93 %gep13 = getelementptr inbounds i8, i8* %ptr, i64 13 94 %gep14 = getelementptr inbounds i8, i8* %ptr, i64 14 95 %gep15 = getelementptr inbounds i8, i8* %ptr, i64 15 96 store i8 %ext00, i8* %gep00, align 1 97 store i8 %ext01, i8* %gep01, align 1 98 store i8 %ext02, i8* %gep02, align 1 99 store i8 %ext03, i8* %gep03, align 1 100 store i8 %ext04, i8* %gep04, align 1 101 store i8 %ext05, i8* %gep05, align 1 102 store i8 %ext06, i8* %gep06, align 1 103 store i8 %ext07, i8* %gep07, align 1 104 store i8 %ext08, i8* %gep08, align 1 105 store i8 %ext09, i8* %gep09, align 1 106 store i8 %ext10, i8* %gep10, align 1 107 store i8 %ext11, i8* %gep11, align 1 108 store i8 %ext12, i8* %gep12, align 1 109 store i8 %ext13, i8* %gep13, align 1 110 store i8 %ext14, i8* %gep14, align 1 111 store i8 %ext15, i8* %gep15, align 1 112 ret void 113} 114 115; PR34217 - https://bugs.llvm.org/show_bug.cgi?id=34217 116 117define void @extract_vector_store_32_consecutive_bytes(<4 x i64> %v, i8* %ptr) #0 { 118; CHECK-LABEL: extract_vector_store_32_consecutive_bytes: 119; CHECK: # %bb.0: 120; CHECK-NEXT: vmovups %ymm0, (%rdi) 121; CHECK-NEXT: vzeroupper 122; CHECK-NEXT: retq 123 %bc = bitcast <4 x i64> %v to <32 x i8> 124 %ext00 = extractelement <32 x i8> %bc, i32 0 125 %ext01 = extractelement <32 x i8> %bc, i32 1 126 %ext02 = extractelement <32 x i8> %bc, i32 2 127 %ext03 = extractelement <32 x i8> %bc, i32 3 128 %ext04 = extractelement <32 x i8> %bc, i32 4 129 %ext05 = extractelement <32 x i8> %bc, i32 5 130 %ext06 = extractelement <32 x i8> %bc, i32 6 131 %ext07 = extractelement <32 x i8> %bc, i32 7 132 %ext08 = extractelement <32 x i8> %bc, i32 8 133 %ext09 = extractelement <32 x i8> %bc, i32 9 134 %ext10 = extractelement <32 x i8> %bc, i32 10 135 %ext11 = extractelement <32 x i8> %bc, i32 11 136 %ext12 = extractelement <32 x i8> %bc, i32 12 137 %ext13 = extractelement <32 x i8> %bc, i32 13 138 %ext14 = extractelement <32 x i8> %bc, i32 14 139 %ext15 = extractelement <32 x i8> %bc, i32 15 140 %ext16 = extractelement <32 x i8> %bc, i32 16 141 %ext17 = extractelement <32 x i8> %bc, i32 17 142 %ext18 = extractelement <32 x i8> %bc, i32 18 143 %ext19 = extractelement <32 x i8> %bc, i32 19 144 %ext20 = extractelement <32 x i8> %bc, i32 20 145 %ext21 = extractelement <32 x i8> %bc, i32 21 146 %ext22 = extractelement <32 x i8> %bc, i32 22 147 %ext23 = extractelement <32 x i8> %bc, i32 23 148 %ext24 = extractelement <32 x i8> %bc, i32 24 149 %ext25 = extractelement <32 x i8> %bc, i32 25 150 %ext26 = extractelement <32 x i8> %bc, i32 26 151 %ext27 = extractelement <32 x i8> %bc, i32 27 152 %ext28 = extractelement <32 x i8> %bc, i32 28 153 %ext29 = extractelement <32 x i8> %bc, i32 29 154 %ext30 = extractelement <32 x i8> %bc, i32 30 155 %ext31 = extractelement <32 x i8> %bc, i32 31 156 %gep00 = getelementptr inbounds i8, i8* %ptr, i64 0 157 %gep01 = getelementptr inbounds i8, i8* %ptr, i64 1 158 %gep02 = getelementptr inbounds i8, i8* %ptr, i64 2 159 %gep03 = getelementptr inbounds i8, i8* %ptr, i64 3 160 %gep04 = getelementptr inbounds i8, i8* %ptr, i64 4 161 %gep05 = getelementptr inbounds i8, i8* %ptr, i64 5 162 %gep06 = getelementptr inbounds i8, i8* %ptr, i64 6 163 %gep07 = getelementptr inbounds i8, i8* %ptr, i64 7 164 %gep08 = getelementptr inbounds i8, i8* %ptr, i64 8 165 %gep09 = getelementptr inbounds i8, i8* %ptr, i64 9 166 %gep10 = getelementptr inbounds i8, i8* %ptr, i64 10 167 %gep11 = getelementptr inbounds i8, i8* %ptr, i64 11 168 %gep12 = getelementptr inbounds i8, i8* %ptr, i64 12 169 %gep13 = getelementptr inbounds i8, i8* %ptr, i64 13 170 %gep14 = getelementptr inbounds i8, i8* %ptr, i64 14 171 %gep15 = getelementptr inbounds i8, i8* %ptr, i64 15 172 %gep16 = getelementptr inbounds i8, i8* %ptr, i64 16 173 %gep17 = getelementptr inbounds i8, i8* %ptr, i64 17 174 %gep18 = getelementptr inbounds i8, i8* %ptr, i64 18 175 %gep19 = getelementptr inbounds i8, i8* %ptr, i64 19 176 %gep20 = getelementptr inbounds i8, i8* %ptr, i64 20 177 %gep21 = getelementptr inbounds i8, i8* %ptr, i64 21 178 %gep22 = getelementptr inbounds i8, i8* %ptr, i64 22 179 %gep23 = getelementptr inbounds i8, i8* %ptr, i64 23 180 %gep24 = getelementptr inbounds i8, i8* %ptr, i64 24 181 %gep25 = getelementptr inbounds i8, i8* %ptr, i64 25 182 %gep26 = getelementptr inbounds i8, i8* %ptr, i64 26 183 %gep27 = getelementptr inbounds i8, i8* %ptr, i64 27 184 %gep28 = getelementptr inbounds i8, i8* %ptr, i64 28 185 %gep29 = getelementptr inbounds i8, i8* %ptr, i64 29 186 %gep30 = getelementptr inbounds i8, i8* %ptr, i64 30 187 %gep31 = getelementptr inbounds i8, i8* %ptr, i64 31 188 store i8 %ext00, i8* %gep00, align 1 189 store i8 %ext01, i8* %gep01, align 1 190 store i8 %ext02, i8* %gep02, align 1 191 store i8 %ext03, i8* %gep03, align 1 192 store i8 %ext04, i8* %gep04, align 1 193 store i8 %ext05, i8* %gep05, align 1 194 store i8 %ext06, i8* %gep06, align 1 195 store i8 %ext07, i8* %gep07, align 1 196 store i8 %ext08, i8* %gep08, align 1 197 store i8 %ext09, i8* %gep09, align 1 198 store i8 %ext10, i8* %gep10, align 1 199 store i8 %ext11, i8* %gep11, align 1 200 store i8 %ext12, i8* %gep12, align 1 201 store i8 %ext13, i8* %gep13, align 1 202 store i8 %ext14, i8* %gep14, align 1 203 store i8 %ext15, i8* %gep15, align 1 204 store i8 %ext16, i8* %gep16, align 1 205 store i8 %ext17, i8* %gep17, align 1 206 store i8 %ext18, i8* %gep18, align 1 207 store i8 %ext19, i8* %gep19, align 1 208 store i8 %ext20, i8* %gep20, align 1 209 store i8 %ext21, i8* %gep21, align 1 210 store i8 %ext22, i8* %gep22, align 1 211 store i8 %ext23, i8* %gep23, align 1 212 store i8 %ext24, i8* %gep24, align 1 213 store i8 %ext25, i8* %gep25, align 1 214 store i8 %ext26, i8* %gep26, align 1 215 store i8 %ext27, i8* %gep27, align 1 216 store i8 %ext28, i8* %gep28, align 1 217 store i8 %ext29, i8* %gep29, align 1 218 store i8 %ext30, i8* %gep30, align 1 219 store i8 %ext31, i8* %gep31, align 1 220 ret void 221} 222 223; https://bugs.llvm.org/show_bug.cgi?id=43446 224define void @pr43446_0(i64 %x) { 225; CHECK-LABEL: pr43446_0: 226; CHECK: # %bb.0: 227; CHECK-NEXT: movb $1, (%rdi) 228; CHECK-NEXT: retq 229 %a = inttoptr i64 %x to i8* 230 store i8 -2, i8* %a, align 1 231 %b = inttoptr i64 %x to i1* 232 store i1 true, i1* %b, align 1 233 ret void 234} 235define void @pr43446_1(i8* %a) { 236; CHECK-LABEL: pr43446_1: 237; CHECK: # %bb.0: 238; CHECK-NEXT: movb $1, (%rdi) 239; CHECK-NEXT: retq 240 store i8 -2, i8* %a, align 1 241 %b = bitcast i8* %a to i1* 242 store i1 true, i1* %b, align 1 243 ret void 244} 245 246define void @rotate16_in_place(i8* %p) { 247; CHECK-LABEL: rotate16_in_place: 248; CHECK: # %bb.0: 249; CHECK-NEXT: rolw $8, (%rdi) 250; CHECK-NEXT: retq 251 %p0 = getelementptr i8, i8* %p, i64 0 252 %p1 = getelementptr i8, i8* %p, i64 1 253 %i0 = load i8, i8* %p0, align 1 254 %i1 = load i8, i8* %p1, align 1 255 store i8 %i1, i8* %p0, align 1 256 store i8 %i0, i8* %p1, align 1 257 ret void 258} 259 260define void @rotate16(i8* %p, i8* %q) { 261; CHECK-LABEL: rotate16: 262; CHECK: # %bb.0: 263; CHECK-NEXT: movzwl (%rdi), %eax 264; CHECK-NEXT: rolw $8, %ax 265; CHECK-NEXT: movw %ax, (%rsi) 266; CHECK-NEXT: retq 267 %p0 = getelementptr i8, i8* %p, i64 0 268 %p1 = getelementptr i8, i8* %p, i64 1 269 %q0 = getelementptr i8, i8* %q, i64 0 270 %q1 = getelementptr i8, i8* %q, i64 1 271 %i0 = load i8, i8* %p0, align 1 272 %i1 = load i8, i8* %p1, align 1 273 store i8 %i1, i8* %q0, align 1 274 store i8 %i0, i8* %q1, align 1 275 ret void 276} 277 278define void @rotate32_in_place(i16* %p) { 279; CHECK-LABEL: rotate32_in_place: 280; CHECK: # %bb.0: 281; CHECK-NEXT: roll $16, (%rdi) 282; CHECK-NEXT: retq 283 %p0 = getelementptr i16, i16* %p, i64 0 284 %p1 = getelementptr i16, i16* %p, i64 1 285 %i0 = load i16, i16* %p0, align 2 286 %i1 = load i16, i16* %p1, align 2 287 store i16 %i1, i16* %p0, align 2 288 store i16 %i0, i16* %p1, align 2 289 ret void 290} 291 292define void @rotate32(i16* %p) { 293; CHECK-LABEL: rotate32: 294; CHECK: # %bb.0: 295; CHECK-NEXT: movl (%rdi), %eax 296; CHECK-NEXT: roll $16, %eax 297; CHECK-NEXT: movl %eax, 84(%rdi) 298; CHECK-NEXT: retq 299 %p0 = getelementptr i16, i16* %p, i64 0 300 %p1 = getelementptr i16, i16* %p, i64 1 301 %p42 = getelementptr i16, i16* %p, i64 42 302 %p43 = getelementptr i16, i16* %p, i64 43 303 %i0 = load i16, i16* %p0, align 2 304 %i1 = load i16, i16* %p1, align 2 305 store i16 %i1, i16* %p42, align 2 306 store i16 %i0, i16* %p43, align 2 307 ret void 308} 309 310define void @rotate64_in_place(i32* %p) { 311; CHECK-LABEL: rotate64_in_place: 312; CHECK: # %bb.0: 313; CHECK-NEXT: rolq $32, (%rdi) 314; CHECK-NEXT: retq 315 %p0 = getelementptr i32, i32* %p, i64 0 316 %p1 = getelementptr i32, i32* %p, i64 1 317 %i0 = load i32, i32* %p0, align 4 318 %i1 = load i32, i32* %p1, align 4 319 store i32 %i1, i32* %p0, align 4 320 store i32 %i0, i32* %p1, align 4 321 ret void 322} 323 324define void @rotate64(i32* %p) { 325; CHECK-LABEL: rotate64: 326; CHECK: # %bb.0: 327; CHECK-NEXT: movq (%rdi), %rax 328; CHECK-NEXT: rolq $32, %rax 329; CHECK-NEXT: movq %rax, 8(%rdi) 330; CHECK-NEXT: retq 331 %p0 = getelementptr i32, i32* %p, i64 0 332 %p1 = getelementptr i32, i32* %p, i64 1 333 %p2 = getelementptr i32, i32* %p, i64 2 334 %p3 = getelementptr i32, i32* %p, i64 3 335 %i0 = load i32, i32* %p0, align 4 336 %i1 = load i32, i32* %p1, align 4 337 store i32 %i1, i32* %p2, align 4 338 store i32 %i0, i32* %p3, align 4 339 ret void 340} 341 342define void @rotate64_iterate(i16* %p) { 343; CHECK-LABEL: rotate64_iterate: 344; CHECK: # %bb.0: 345; CHECK-NEXT: movq (%rdi), %rax 346; CHECK-NEXT: rolq $32, %rax 347; CHECK-NEXT: movq %rax, 84(%rdi) 348; CHECK-NEXT: retq 349 %p0 = getelementptr i16, i16* %p, i64 0 350 %p1 = getelementptr i16, i16* %p, i64 1 351 %p2 = getelementptr i16, i16* %p, i64 2 352 %p3 = getelementptr i16, i16* %p, i64 3 353 %p42 = getelementptr i16, i16* %p, i64 42 354 %p43 = getelementptr i16, i16* %p, i64 43 355 %p44 = getelementptr i16, i16* %p, i64 44 356 %p45 = getelementptr i16, i16* %p, i64 45 357 %i0 = load i16, i16* %p0, align 2 358 %i1 = load i16, i16* %p1, align 2 359 %i2 = load i16, i16* %p2, align 2 360 %i3 = load i16, i16* %p3, align 2 361 store i16 %i2, i16* %p42, align 2 362 store i16 %i3, i16* %p43, align 2 363 store i16 %i0, i16* %p44, align 2 364 store i16 %i1, i16* %p45, align 2 365 ret void 366} 367 368; TODO: recognize this as 2 rotates? 369 370define void @rotate32_consecutive(i16* %p) { 371; CHECK-LABEL: rotate32_consecutive: 372; CHECK: # %bb.0: 373; CHECK-NEXT: movzwl (%rdi), %eax 374; CHECK-NEXT: movzwl 2(%rdi), %ecx 375; CHECK-NEXT: movzwl 4(%rdi), %edx 376; CHECK-NEXT: movzwl 6(%rdi), %esi 377; CHECK-NEXT: movw %cx, 84(%rdi) 378; CHECK-NEXT: movw %ax, 86(%rdi) 379; CHECK-NEXT: movw %si, 88(%rdi) 380; CHECK-NEXT: movw %dx, 90(%rdi) 381; CHECK-NEXT: retq 382 %p0 = getelementptr i16, i16* %p, i64 0 383 %p1 = getelementptr i16, i16* %p, i64 1 384 %p2 = getelementptr i16, i16* %p, i64 2 385 %p3 = getelementptr i16, i16* %p, i64 3 386 %p42 = getelementptr i16, i16* %p, i64 42 387 %p43 = getelementptr i16, i16* %p, i64 43 388 %p44 = getelementptr i16, i16* %p, i64 44 389 %p45 = getelementptr i16, i16* %p, i64 45 390 %i0 = load i16, i16* %p0, align 2 391 %i1 = load i16, i16* %p1, align 2 392 %i2 = load i16, i16* %p2, align 2 393 %i3 = load i16, i16* %p3, align 2 394 store i16 %i1, i16* %p42, align 2 395 store i16 %i0, i16* %p43, align 2 396 store i16 %i3, i16* %p44, align 2 397 store i16 %i2, i16* %p45, align 2 398 ret void 399} 400 401; Same as above, but now the stores are not all consecutive. 402 403define void @rotate32_twice(i16* %p) { 404; CHECK-LABEL: rotate32_twice: 405; CHECK: # %bb.0: 406; CHECK-NEXT: movl (%rdi), %eax 407; CHECK-NEXT: movl 4(%rdi), %ecx 408; CHECK-NEXT: roll $16, %eax 409; CHECK-NEXT: roll $16, %ecx 410; CHECK-NEXT: movl %eax, 84(%rdi) 411; CHECK-NEXT: movl %ecx, 108(%rdi) 412; CHECK-NEXT: retq 413 %p0 = getelementptr i16, i16* %p, i64 0 414 %p1 = getelementptr i16, i16* %p, i64 1 415 %p2 = getelementptr i16, i16* %p, i64 2 416 %p3 = getelementptr i16, i16* %p, i64 3 417 %p42 = getelementptr i16, i16* %p, i64 42 418 %p43 = getelementptr i16, i16* %p, i64 43 419 %p54 = getelementptr i16, i16* %p, i64 54 420 %p55 = getelementptr i16, i16* %p, i64 55 421 %i0 = load i16, i16* %p0, align 2 422 %i1 = load i16, i16* %p1, align 2 423 %i2 = load i16, i16* %p2, align 2 424 %i3 = load i16, i16* %p3, align 2 425 store i16 %i1, i16* %p42, align 2 426 store i16 %i0, i16* %p43, align 2 427 store i16 %i3, i16* %p54, align 2 428 store i16 %i2, i16* %p55, align 2 429 ret void 430} 431 432define void @trunc_i16_to_i8(i16 %x, i8* %p) { 433; CHECK-LABEL: trunc_i16_to_i8: 434; CHECK: # %bb.0: 435; CHECK-NEXT: movw %di, (%rsi) 436; CHECK-NEXT: retq 437 %t1 = trunc i16 %x to i8 438 %sh = lshr i16 %x, 8 439 %t2 = trunc i16 %sh to i8 440 store i8 %t1, i8* %p, align 1 441 %p1 = getelementptr inbounds i8, i8* %p, i64 1 442 store i8 %t2, i8* %p1, align 1 443 ret void 444} 445 446define void @trunc_i32_to_i8(i32 %x, i8* %p) { 447; CHECK-LABEL: trunc_i32_to_i8: 448; CHECK: # %bb.0: 449; CHECK-NEXT: movl %edi, (%rsi) 450; CHECK-NEXT: retq 451 %t1 = trunc i32 %x to i8 452 %sh1 = lshr i32 %x, 8 453 %t2 = trunc i32 %sh1 to i8 454 %sh2 = lshr i32 %x, 16 455 %t3 = trunc i32 %sh2 to i8 456 %sh3 = lshr i32 %x, 24 457 %t4 = trunc i32 %sh3 to i8 458 store i8 %t1, i8* %p, align 1 459 %p1 = getelementptr inbounds i8, i8* %p, i64 1 460 store i8 %t2, i8* %p1, align 1 461 %p2 = getelementptr inbounds i8, i8* %p, i64 2 462 store i8 %t3, i8* %p2, align 1 463 %p3 = getelementptr inbounds i8, i8* %p, i64 3 464 store i8 %t4, i8* %p3, align 1 465 ret void 466} 467 468define void @trunc_i32_to_i16(i32 %x, i16* %p) { 469; CHECK-LABEL: trunc_i32_to_i16: 470; CHECK: # %bb.0: 471; CHECK-NEXT: movl %edi, (%rsi) 472; CHECK-NEXT: retq 473 %t1 = trunc i32 %x to i16 474 %sh = lshr i32 %x, 16 475 %t2 = trunc i32 %sh to i16 476 store i16 %t1, i16* %p, align 2 477 %p1 = getelementptr inbounds i16, i16* %p, i64 1 478 store i16 %t2, i16* %p1, align 2 479 ret void 480} 481 482define void @be_i32_to_i16(i32 %x, i16* %p0) { 483; CHECK-LABEL: be_i32_to_i16: 484; CHECK: # %bb.0: 485; CHECK-NEXT: rorl $16, %edi 486; CHECK-NEXT: movl %edi, (%rsi) 487; CHECK-NEXT: retq 488 %sh1 = lshr i32 %x, 16 489 %t0 = trunc i32 %x to i16 490 %t1 = trunc i32 %sh1 to i16 491 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 492 store i16 %t0, i16* %p1, align 2 493 store i16 %t1, i16* %p0, align 2 494 ret void 495} 496 497define void @be_i32_to_i16_order(i32 %x, i16* %p0) { 498; CHECK-LABEL: be_i32_to_i16_order: 499; CHECK: # %bb.0: 500; CHECK-NEXT: rorl $16, %edi 501; CHECK-NEXT: movl %edi, (%rsi) 502; CHECK-NEXT: retq 503 %sh1 = lshr i32 %x, 16 504 %t0 = trunc i32 %x to i16 505 %t1 = trunc i32 %sh1 to i16 506 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 507 store i16 %t1, i16* %p0, align 2 508 store i16 %t0, i16* %p1, align 2 509 ret void 510} 511 512define void @trunc_i64_to_i8(i64 %x, i8* %p) { 513; CHECK-LABEL: trunc_i64_to_i8: 514; CHECK: # %bb.0: 515; CHECK-NEXT: movq %rdi, (%rsi) 516; CHECK-NEXT: retq 517 %t1 = trunc i64 %x to i8 518 %sh1 = lshr i64 %x, 8 519 %t2 = trunc i64 %sh1 to i8 520 %sh2 = lshr i64 %x, 16 521 %t3 = trunc i64 %sh2 to i8 522 %sh3 = lshr i64 %x, 24 523 %t4 = trunc i64 %sh3 to i8 524 %sh4 = lshr i64 %x, 32 525 %t5 = trunc i64 %sh4 to i8 526 %sh5 = lshr i64 %x, 40 527 %t6 = trunc i64 %sh5 to i8 528 %sh6 = lshr i64 %x, 48 529 %t7 = trunc i64 %sh6 to i8 530 %sh7 = lshr i64 %x, 56 531 %t8 = trunc i64 %sh7 to i8 532 store i8 %t1, i8* %p, align 1 533 %p1 = getelementptr inbounds i8, i8* %p, i64 1 534 store i8 %t2, i8* %p1, align 1 535 %p2 = getelementptr inbounds i8, i8* %p, i64 2 536 store i8 %t3, i8* %p2, align 1 537 %p3 = getelementptr inbounds i8, i8* %p, i64 3 538 store i8 %t4, i8* %p3, align 1 539 %p4 = getelementptr inbounds i8, i8* %p, i64 4 540 store i8 %t5, i8* %p4, align 1 541 %p5 = getelementptr inbounds i8, i8* %p, i64 5 542 store i8 %t6, i8* %p5, align 1 543 %p6 = getelementptr inbounds i8, i8* %p, i64 6 544 store i8 %t7, i8* %p6, align 1 545 %p7 = getelementptr inbounds i8, i8* %p, i64 7 546 store i8 %t8, i8* %p7, align 1 547 ret void 548} 549 550define void @trunc_i64_to_i16(i64 %x, i16* %p) { 551; CHECK-LABEL: trunc_i64_to_i16: 552; CHECK: # %bb.0: 553; CHECK-NEXT: movq %rdi, (%rsi) 554; CHECK-NEXT: retq 555 %t1 = trunc i64 %x to i16 556 %sh1 = lshr i64 %x, 16 557 %t2 = trunc i64 %sh1 to i16 558 %sh2 = lshr i64 %x, 32 559 %t3 = trunc i64 %sh2 to i16 560 %sh3 = lshr i64 %x, 48 561 %t4 = trunc i64 %sh3 to i16 562 store i16 %t1, i16* %p, align 2 563 %p1 = getelementptr inbounds i16, i16* %p, i64 1 564 store i16 %t2, i16* %p1, align 2 565 %p2 = getelementptr inbounds i16, i16* %p, i64 2 566 store i16 %t3, i16* %p2, align 2 567 %p3 = getelementptr inbounds i16, i16* %p, i64 3 568 store i16 %t4, i16* %p3, align 2 569 ret void 570} 571 572define void @trunc_i64_to_i32(i64 %x, i32* %p) { 573; CHECK-LABEL: trunc_i64_to_i32: 574; CHECK: # %bb.0: 575; CHECK-NEXT: movq %rdi, (%rsi) 576; CHECK-NEXT: retq 577 %t1 = trunc i64 %x to i32 578 %sh = lshr i64 %x, 32 579 %t2 = trunc i64 %sh to i32 580 store i32 %t1, i32* %p, align 4 581 %p1 = getelementptr inbounds i32, i32* %p, i64 1 582 store i32 %t2, i32* %p1, align 4 583 ret void 584} 585 586define void @be_i64_to_i32(i64 %x, i32* %p0) { 587; CHECK-LABEL: be_i64_to_i32: 588; CHECK: # %bb.0: 589; CHECK-NEXT: rorq $32, %rdi 590; CHECK-NEXT: movq %rdi, (%rsi) 591; CHECK-NEXT: retq 592 %sh1 = lshr i64 %x, 32 593 %t0 = trunc i64 %x to i32 594 %t1 = trunc i64 %sh1 to i32 595 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 596 store i32 %t0, i32* %p1, align 4 597 store i32 %t1, i32* %p0, align 4 598 ret void 599} 600 601define void @be_i64_to_i32_order(i64 %x, i32* %p0) { 602; CHECK-LABEL: be_i64_to_i32_order: 603; CHECK: # %bb.0: 604; CHECK-NEXT: rorq $32, %rdi 605; CHECK-NEXT: movq %rdi, (%rsi) 606; CHECK-NEXT: retq 607 %sh1 = lshr i64 %x, 32 608 %t0 = trunc i64 %x to i32 609 %t1 = trunc i64 %sh1 to i32 610 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 611 store i32 %t1, i32* %p0, align 4 612 store i32 %t0, i32* %p1, align 4 613 ret void 614} 615