| ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc < %s -mtriple=x86_64-linux-gnu -stop-after=finalize-isel | FileCheck %s |
| |
| ; Make sure the memory operand of the MOV32mr is correct. For a constant |
| ; offset, use the explicit alignment of the pointer; for a variable offset, |
| ; reduce the alignment. |
| |
| define void @constant_offset_insert(ptr %g, i32 %eltval) { |
| ; CHECK-LABEL: name: constant_offset_insert |
| ; CHECK: bb.0 (%ir-block.0): |
| ; CHECK-NEXT: liveins: $rdi, $esi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $esi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: MOV32mr [[COPY1]], 1, $noreg, 4, $noreg, [[COPY]] :: (store (s32) into %ir.g + 4, basealign 16) |
| ; CHECK-NEXT: RET 0 |
| %vec = load <4 x i32>, ptr %g, align 16 |
| %insert = insertelement <4 x i32> %vec, i32 %eltval, i32 1 |
| store <4 x i32> %insert, ptr %g, align 16 |
| ret void |
| } |
| |
| define void @variable_offset_insert(ptr %g, i32 %eltval, i32 %offset) { |
| ; CHECK-LABEL: name: variable_offset_insert |
| ; CHECK: bb.0 (%ir-block.0): |
| ; CHECK-NEXT: liveins: $rdi, $esi, $edx |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edx |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY]], 3, implicit-def dead $eflags |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64_nosp = SUBREG_TO_REG killed [[AND32ri]], %subreg.sub_32bit |
| ; CHECK-NEXT: MOV32mr [[COPY2]], 4, killed [[SUBREG_TO_REG]], 0, $noreg, [[COPY1]] :: (store (s32)) |
| ; CHECK-NEXT: RET 0 |
| %vec = load <4 x i32>, ptr %g, align 16 |
| %insert = insertelement <4 x i32> %vec, i32 %eltval, i32 %offset |
| store <4 x i32> %insert, ptr %g, align 16 |
| ret void |
| } |
| |
| define void @variable_offset_insert_unaligned(ptr %g, i32 %eltval, i32 %offset) { |
| ; CHECK-LABEL: name: variable_offset_insert_unaligned |
| ; CHECK: bb.0 (%ir-block.0): |
| ; CHECK-NEXT: liveins: $rdi, $esi, $edx |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edx |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY]], 3, implicit-def dead $eflags |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64_nosp = SUBREG_TO_REG killed [[AND32ri]], %subreg.sub_32bit |
| ; CHECK-NEXT: MOV32mr [[COPY2]], 4, killed [[SUBREG_TO_REG]], 0, $noreg, [[COPY1]] :: (store (s32), align 1) |
| ; CHECK-NEXT: RET 0 |
| %vec = load <4 x i32>, ptr %g, align 1 |
| %insert = insertelement <4 x i32> %vec, i32 %eltval, i32 %offset |
| store <4 x i32> %insert, ptr %g, align 1 |
| ret void |
| } |