| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -mtriple=x86_64-unknown-unknown -force-split-store < %s | FileCheck %s |
| |
| define void @int32_float_pair(i32 %tmp1, float %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int32_float_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movl %edi, (%rsi) |
| ; CHECK-NEXT: movss %xmm0, 4(%rsi) |
| ; CHECK-NEXT: retq |
| %t0 = bitcast float %tmp2 to i32 |
| %t1 = zext i32 %t0 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i32 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @float_int32_pair(float %tmp1, i32 %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: float_int32_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movss %xmm0, (%rsi) |
| ; CHECK-NEXT: movl %edi, 4(%rsi) |
| ; CHECK-NEXT: retq |
| %t0 = bitcast float %tmp1 to i32 |
| %t1 = zext i32 %tmp2 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i32 %t0 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int16_float_pair(i16 signext %tmp1, float %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int16_float_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movzwl %di, %eax |
| ; CHECK-NEXT: movl %eax, (%rsi) |
| ; CHECK-NEXT: movss %xmm0, 4(%rsi) |
| ; CHECK-NEXT: retq |
| %t0 = bitcast float %tmp2 to i32 |
| %t1 = zext i32 %t0 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i16 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int8_float_pair(i8 signext %tmp1, float %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int8_float_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movzbl %dil, %eax |
| ; CHECK-NEXT: movl %eax, (%rsi) |
| ; CHECK-NEXT: movss %xmm0, 4(%rsi) |
| ; CHECK-NEXT: retq |
| %t0 = bitcast float %tmp2 to i32 |
| %t1 = zext i32 %t0 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i8 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int32_int32_pair(i32 %tmp1, i32 %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int32_int32_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movl %edi, (%rdx) |
| ; CHECK-NEXT: movl %esi, 4(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i32 %tmp2 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i32 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int16_int16_pair(i16 signext %tmp1, i16 signext %tmp2, i32* %ref.tmp) { |
| ; CHECK-LABEL: int16_int16_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movw %di, (%rdx) |
| ; CHECK-NEXT: movw %si, 2(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i16 %tmp2 to i32 |
| %t2 = shl nuw i32 %t1, 16 |
| %t3 = zext i16 %tmp1 to i32 |
| %t4 = or i32 %t2, %t3 |
| store i32 %t4, i32* %ref.tmp, align 4 |
| ret void |
| } |
| |
| define void @int8_int8_pair(i8 signext %tmp1, i8 signext %tmp2, i16* %ref.tmp) { |
| ; CHECK-LABEL: int8_int8_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movb %dil, (%rdx) |
| ; CHECK-NEXT: movb %sil, 1(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i8 %tmp2 to i16 |
| %t2 = shl nuw i16 %t1, 8 |
| %t3 = zext i8 %tmp1 to i16 |
| %t4 = or i16 %t2, %t3 |
| store i16 %t4, i16* %ref.tmp, align 2 |
| ret void |
| } |
| |
| define void @int31_int31_pair(i31 %tmp1, i31 %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int31_int31_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: andl $2147483647, %edi # imm = 0x7FFFFFFF |
| ; CHECK-NEXT: movl %edi, (%rdx) |
| ; CHECK-NEXT: andl $2147483647, %esi # imm = 0x7FFFFFFF |
| ; CHECK-NEXT: movl %esi, 4(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i31 %tmp2 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i31 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int31_int17_pair(i31 %tmp1, i17 %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: int31_int17_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: andl $2147483647, %edi # imm = 0x7FFFFFFF |
| ; CHECK-NEXT: movl %edi, (%rdx) |
| ; CHECK-NEXT: andl $131071, %esi # imm = 0x1FFFF |
| ; CHECK-NEXT: movl %esi, 4(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i17 %tmp2 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i31 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @int7_int3_pair(i7 signext %tmp1, i3 signext %tmp2, i16* %ref.tmp) { |
| ; CHECK-LABEL: int7_int3_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: andb $127, %dil |
| ; CHECK-NEXT: movb %dil, (%rdx) |
| ; CHECK-NEXT: andb $7, %sil |
| ; CHECK-NEXT: movb %sil, 1(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i3 %tmp2 to i16 |
| %t2 = shl nuw i16 %t1, 8 |
| %t3 = zext i7 %tmp1 to i16 |
| %t4 = or i16 %t2, %t3 |
| store i16 %t4, i16* %ref.tmp, align 2 |
| ret void |
| } |
| |
| define void @int24_int24_pair(i24 signext %tmp1, i24 signext %tmp2, i48* %ref.tmp) { |
| ; CHECK-LABEL: int24_int24_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movw %di, (%rdx) |
| ; CHECK-NEXT: shrl $16, %edi |
| ; CHECK-NEXT: movb %dil, 2(%rdx) |
| ; CHECK-NEXT: movw %si, 4(%rdx) |
| ; CHECK-NEXT: shrl $16, %esi |
| ; CHECK-NEXT: movb %sil, 6(%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i24 %tmp2 to i48 |
| %t2 = shl nuw i48 %t1, 24 |
| %t3 = zext i24 %tmp1 to i48 |
| %t4 = or i48 %t2, %t3 |
| store i48 %t4, i48* %ref.tmp, align 2 |
| ret void |
| } |
| |
| ; getTypeSizeInBits(i12) != getTypeStoreSizeInBits(i12), so store split doesn't kick in. |
| |
| define void @int12_int12_pair(i12 signext %tmp1, i12 signext %tmp2, i24* %ref.tmp) { |
| ; CHECK-LABEL: int12_int12_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: movl %esi, %eax |
| ; CHECK-NEXT: shll $12, %eax |
| ; CHECK-NEXT: andl $4095, %edi # imm = 0xFFF |
| ; CHECK-NEXT: orl %eax, %edi |
| ; CHECK-NEXT: shrl $4, %esi |
| ; CHECK-NEXT: movb %sil, 2(%rdx) |
| ; CHECK-NEXT: movw %di, (%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i12 %tmp2 to i24 |
| %t2 = shl nuw i24 %t1, 12 |
| %t3 = zext i12 %tmp1 to i24 |
| %t4 = or i24 %t2, %t3 |
| store i24 %t4, i24* %ref.tmp, align 2 |
| ret void |
| } |
| |
| ; getTypeSizeInBits(i14) != getTypeStoreSizeInBits(i14), so store split doesn't kick in. |
| |
| define void @int7_int7_pair(i7 signext %tmp1, i7 signext %tmp2, i14* %ref.tmp) { |
| ; CHECK-LABEL: int7_int7_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: shll $7, %esi |
| ; CHECK-NEXT: andl $127, %edi |
| ; CHECK-NEXT: orl %esi, %edi |
| ; CHECK-NEXT: andl $16383, %edi # imm = 0x3FFF |
| ; CHECK-NEXT: movw %di, (%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i7 %tmp2 to i14 |
| %t2 = shl nuw i14 %t1, 7 |
| %t3 = zext i7 %tmp1 to i14 |
| %t4 = or i14 %t2, %t3 |
| store i14 %t4, i14* %ref.tmp, align 2 |
| ret void |
| } |
| |
| ; getTypeSizeInBits(i2) != getTypeStoreSizeInBits(i2), so store split doesn't kick in. |
| |
| define void @int1_int1_pair(i1 signext %tmp1, i1 signext %tmp2, i2* %ref.tmp) { |
| ; CHECK-LABEL: int1_int1_pair: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: addb %sil, %sil |
| ; CHECK-NEXT: subb %dil, %sil |
| ; CHECK-NEXT: andb $3, %sil |
| ; CHECK-NEXT: movb %sil, (%rdx) |
| ; CHECK-NEXT: retq |
| %t1 = zext i1 %tmp2 to i2 |
| %t2 = shl nuw i2 %t1, 1 |
| %t3 = zext i1 %tmp1 to i2 |
| %t4 = or i2 %t2, %t3 |
| store i2 %t4, i2* %ref.tmp, align 1 |
| ret void |
| } |
| |
| define void @mbb_int32_float_pair(i32 %tmp1, float %tmp2, i64* %ref.tmp) { |
| ; CHECK-LABEL: mbb_int32_float_pair: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: movl %edi, (%rsi) |
| ; CHECK-NEXT: movss %xmm0, 4(%rsi) |
| ; CHECK-NEXT: retq |
| entry: |
| %t0 = bitcast float %tmp2 to i32 |
| br label %next |
| next: |
| %t1 = zext i32 %t0 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i32 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| ret void |
| } |
| |
| define void @mbb_int32_float_multi_stores(i32 %tmp1, float %tmp2, i64* %ref.tmp, i64* %ref.tmp1, i1 %cmp) { |
| ; CHECK-LABEL: mbb_int32_float_multi_stores: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: movl %edi, (%rsi) |
| ; CHECK-NEXT: movss %xmm0, 4(%rsi) |
| ; CHECK-NEXT: testb $1, %cl |
| ; CHECK-NEXT: je .LBB15_2 |
| ; CHECK-NEXT: # %bb.1: # %bb2 |
| ; CHECK-NEXT: movl %edi, (%rdx) |
| ; CHECK-NEXT: movss %xmm0, 4(%rdx) |
| ; CHECK-NEXT: .LBB15_2: # %exitbb |
| ; CHECK-NEXT: retq |
| entry: |
| %t0 = bitcast float %tmp2 to i32 |
| br label %bb1 |
| bb1: |
| %t1 = zext i32 %t0 to i64 |
| %t2 = shl nuw i64 %t1, 32 |
| %t3 = zext i32 %tmp1 to i64 |
| %t4 = or i64 %t2, %t3 |
| store i64 %t4, i64* %ref.tmp, align 8 |
| br i1 %cmp, label %bb2, label %exitbb |
| bb2: |
| store i64 %t4, i64* %ref.tmp1, align 8 |
| br label %exitbb |
| exitbb: |
| ret void |
| } |