Files
clang-p2996/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
Sjoerd Meijer 7efabe5c7d [MIR][ARM] MachineOperand comments
This adds infrastructure to print and parse MIR MachineOperand comments.
The motivation for the ARM backend is to print condition code names instead of
magic constants that are difficult to read (for human beings). For example,
instead of this:

  dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg
  t2Bcc %bb.4, 0, killed $cpsr

we now print this:

  dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14 /* CC::always */, $noreg
  t2Bcc %bb.4, 0 /* CC:eq */, killed $cpsr

This shows that MachineOperand comments are enclosed between /* and */. In this
example, the EOR instruction is not conditionally executed (i.e. it is "always
executed"), which is encoded by the 14 immediate machine operand. Thus, now
this machine operand has /* CC::always */ as a comment. The 0 on the next
conditional branch instruction represents the equal condition code, thus now
this operand has /* CC:eq */ as a comment.

As it is a comment, the MI lexer/parser completely ignores it. The benefit is
that this keeps the change in the lexer extremely minimal and no target
specific parsing needs to be done. The changes on the MIPrinter side are also
minimal, as there is only one target hooks that is used to create the machine
operand comments.

Differential Revision: https://reviews.llvm.org/D74306
2020-02-24 14:19:21 +00:00

569 lines
24 KiB
LLVM

; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE
; RUN: llc -mtriple armeb-unknown -mattr=+vfp2,+v4t -global-isel -global-isel-abort=0 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG
define void @test_void_return() {
; CHECK-LABEL: name: test_void_return
; CHECK: BX_RET 14 /* CC::al */, $noreg
entry:
ret void
}
define signext i1 @test_add_i1(i1 %x, i1 %y) {
; CHECK-LABEL: name: test_add_i1
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s1) = G_TRUNC [[VREGR0]]
; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s1) = G_TRUNC [[VREGR1]]
; CHECK: [[SUM:%[0-9]+]]:_(s1) = G_ADD [[VREGX]], [[VREGY]]
; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_SEXT [[SUM]]
; CHECK: $r0 = COPY [[EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i1 %x, %y
ret i1 %sum
}
define i8 @test_add_i8(i8 %x, i8 %y) {
; CHECK-LABEL: name: test_add_i8
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR1]]
; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGX]], [[VREGY]]
; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
; CHECK: $r0 = COPY [[SUM_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i8 %x, %y
ret i8 %sum
}
define i8 @test_sub_i8(i8 %x, i8 %y) {
; CHECK-LABEL: name: test_sub_i8
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR1]]
; CHECK: [[RES:%[0-9]+]]:_(s8) = G_SUB [[VREGX]], [[VREGY]]
; CHECK: [[RES_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[RES]]
; CHECK: $r0 = COPY [[RES_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%res = sub i8 %x, %y
ret i8 %res
}
define signext i8 @test_return_sext_i8(i8 %x) {
; CHECK-LABEL: name: test_return_sext_i8
; CHECK: liveins: $r0
; CHECK: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK: [[VREG:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
; CHECK: [[VREGEXT:%[0-9]+]]:_(s32) = G_SEXT [[VREG]]
; CHECK: $r0 = COPY [[VREGEXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
ret i8 %x
}
define i16 @test_add_i16(i16 %x, i16 %y) {
; CHECK-LABEL: name: test_add_i16
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
; CHECK: [[SUM:%[0-9]+]]:_(s16) = G_ADD [[VREGX]], [[VREGY]]
; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
; CHECK: $r0 = COPY [[SUM_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i16 %x, %y
ret i16 %sum
}
define i16 @test_sub_i16(i16 %x, i16 %y) {
; CHECK-LABEL: name: test_sub_i16
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
; CHECK: [[RES:%[0-9]+]]:_(s16) = G_SUB [[VREGX]], [[VREGY]]
; CHECK: [[RES_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[RES]]
; CHECK: $r0 = COPY [[RES_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%res = sub i16 %x, %y
ret i16 %res
}
define zeroext i16 @test_return_zext_i16(i16 %x) {
; CHECK-LABEL: name: test_return_zext_i16
; CHECK: liveins: $r0
; CHECK: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
; CHECK: [[VREG:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
; CHECK: [[VREGEXT:%[0-9]+]]:_(s32) = G_ZEXT [[VREG]]
; CHECK: $r0 = COPY [[VREGEXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
ret i16 %x
}
define i32 @test_add_i32(i32 %x, i32 %y) {
; CHECK-LABEL: name: test_add_i32
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s32) = COPY $r1
; CHECK: [[SUM:%[0-9]+]]:_(s32) = G_ADD [[VREGX]], [[VREGY]]
; CHECK: $r0 = COPY [[SUM]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i32 %x, %y
ret i32 %sum
}
define i32 @test_sub_i32(i32 %x, i32 %y) {
; CHECK-LABEL: name: test_sub_i32
; CHECK: liveins: $r0, $r1
; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s32) = COPY $r1
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SUB [[VREGX]], [[VREGY]]
; CHECK: $r0 = COPY [[RES]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%res = sub i32 %x, %y
ret i32 %res
}
define i32 @test_stack_args(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
; CHECK-LABEL: name: test_stack_args
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 4
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 4
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[VREGP2:%[0-9]+]]:_(s32) = COPY $r2
; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
; CHECK: [[VREGP5:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]]{{.*}}load 4
; CHECK: [[SUM:%[0-9]+]]:_(s32) = G_ADD [[VREGP2]], [[VREGP5]]
; CHECK: $r0 = COPY [[SUM]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i32 %p2, %p5
ret i32 %sum
}
define i16 @test_stack_args_signext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
i8 signext %p4, i16 signext %p5) {
; CHECK-LABEL: name: test_stack_args_signext
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK: [[VREGP1:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
; CHECK: [[VREGP5EXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
; CHECK: [[VREGP5:%[0-9]+]]:_(s16) = G_TRUNC [[VREGP5EXT]]
; CHECK: [[SUM:%[0-9]+]]:_(s16) = G_ADD [[VREGP1]], [[VREGP5]]
; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
; CHECK: $r0 = COPY [[SUM_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i16 %p1, %p5
ret i16 %sum
}
define i8 @test_stack_args_zeroext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
i8 zeroext %p4, i16 zeroext %p5) {
; CHECK-LABEL: name: test_stack_args_zeroext
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[VREGR2:%[0-9]+]]:_(s32) = COPY $r2
; CHECK: [[VREGP2:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR2]]
; CHECK: [[FIP4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
; CHECK: [[VREGP4EXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP4]](p0){{.*}}load 4
; CHECK: [[VREGP4:%[0-9]+]]:_(s8) = G_TRUNC [[VREGP4EXT]]
; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGP2]], [[VREGP4]]
; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
; CHECK: $r0 = COPY [[SUM_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i8 %p2, %p4
ret i8 %sum
}
define i8 @test_stack_args_noext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
i8 %p4, i16 %p5) {
; CHECK-LABEL: name: test_stack_args_noext
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[VREGR2:%[0-9]+]]:_(s32) = COPY $r2
; CHECK: [[VREGP2:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR2]]
; CHECK: [[FIP4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
; CHECK: [[VREGP4:%[0-9]+]]:_(s8) = G_LOAD [[FIP4]](p0){{.*}}load 1
; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGP2]], [[VREGP4]]
; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
; CHECK: $r0 = COPY [[SUM_EXT]](s32)
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%sum = add i8 %p2, %p4
ret i8 %sum
}
define zeroext i16 @test_stack_args_extend_the_extended(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
i8 signext %p4, i16 signext %p5) {
; CHECK-LABEL: name: test_stack_args_extend_the_extended
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
; CHECK: [[VREGP5SEXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
; CHECK: [[VREGP5:%[0-9]+]]:_(s16) = G_TRUNC [[VREGP5SEXT]]
; CHECK: [[VREGP5ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[VREGP5]]
; CHECK: $r0 = COPY [[VREGP5ZEXT]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
ret i16 %p5
}
define i16 @test_ptr_arg(i16* %p) {
; CHECK-LABEL: name: test_ptr_arg
; CHECK: liveins: $r0
; CHECK: [[VREGP:%[0-9]+]]:_(p0) = COPY $r0
; CHECK: [[VREGV:%[0-9]+]]:_(s16) = G_LOAD [[VREGP]](p0){{.*}}load 2
entry:
%v = load i16, i16* %p
ret i16 %v
}
define i32* @test_ptr_ret(i32** %p) {
; Test pointer returns and pointer-to-pointer arguments
; CHECK-LABEL: name: test_ptr_ret
; CHECK: liveins: $r0
; CHECK: [[VREGP:%[0-9]+]]:_(p0) = COPY $r0
; CHECK: [[VREGV:%[0-9]+]]:_(p0) = G_LOAD [[VREGP]](p0){{.*}}load 4
; CHECK: $r0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%v = load i32*, i32** %p
ret i32* %v
}
define i32 @test_ptr_arg_on_stack(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32* %p) {
; CHECK-LABEL: name: test_ptr_arg_on_stack
; CHECK: fixedStack:
; CHECK: id: [[P:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[FIP:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P]]
; CHECK: [[VREGP:%[0-9]+]]:_(p0) = G_LOAD [[FIP]](p0){{.*}}load 4
; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_LOAD [[VREGP]](p0){{.*}}load 4
; CHECK: $r0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%v = load i32, i32* %p
ret i32 %v
}
define arm_aapcscc float @test_float_aapcscc(float %p0, float %p1, float %p2,
float %p3, float %p4, float %p5) {
; CHECK-LABEL: name: test_float_aapcscc
; CHECK: fixedStack:
; CHECK-DAG: id: [[P4:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
; CHECK-DAG: id: [[P5:[0-9]+]]{{.*}}offset: 4{{.*}}size: 4
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: [[VREGP1:%[0-9]+]]:_(s32) = COPY $r1
; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
; CHECK: [[VREGP5:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_FADD [[VREGP1]], [[VREGP5]]
; CHECK: $r0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
entry:
%v = fadd float %p1, %p5
ret float %v
}
define arm_aapcs_vfpcc float @test_float_vfpcc(float %p0, float %p1, float %p2,
float %p3, float %p4, float %p5,
float %ridiculous,
float %number,
float %of,
float %parameters,
float %that,
float %should,
float %never,
float %exist,
float %in,
float %practice,
float %q0, float %q1) {
; CHECK-LABEL: name: test_float_vfpcc
; CHECK: fixedStack:
; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 4{{.*}}size: 4
; CHECK: liveins: $s0, $s1, $s2, $s3, $s4, $s5, $s6, $s7, $s8, $s9, $s10, $s11, $s12, $s13, $s14, $s15
; CHECK: [[VREGP1:%[0-9]+]]:_(s32) = COPY $s1
; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
; CHECK: [[VREGQ1:%[0-9]+]]:_(s32) = G_LOAD [[FIQ1]](p0){{.*}}load 4
; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_FADD [[VREGP1]], [[VREGQ1]]
; CHECK: $s0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $s0
entry:
%v = fadd float %p1, %q1
ret float %v
}
define arm_aapcs_vfpcc double @test_double_vfpcc(double %p0, double %p1, double %p2,
double %p3, double %p4, double %p5,
double %reasonable,
double %parameters,
double %q0, double %q1) {
; CHECK-LABEL: name: test_double_vfpcc
; CHECK: fixedStack:
; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
; CHECK: liveins: $d0, $d1, $d2, $d3, $d4, $d5, $d6, $d7
; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = COPY $d1
; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
; CHECK: [[VREGQ1:%[0-9]+]]:_(s64) = G_LOAD [[FIQ1]](p0){{.*}}load 8
; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGQ1]]
; CHECK: $d0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $d0
entry:
%v = fadd double %p1, %q1
ret double %v
}
define arm_aapcscc double @test_double_aapcscc(double %p0, double %p1, double %p2,
double %p3, double %p4, double %p5) {
; CHECK-LABEL: name: test_double_aapcscc
; CHECK: fixedStack:
; CHECK-DAG: id: [[P2:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
; CHECK-DAG: id: [[P3:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
; CHECK-DAG: id: [[P4:[0-9]+]]{{.*}}offset: 16{{.*}}size: 8
; CHECK-DAG: id: [[P5:[0-9]+]]{{.*}}offset: 24{{.*}}size: 8
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK-DAG: [[VREGP1LO:%[0-9]+]]:_(s32) = COPY $r2
; CHECK-DAG: [[VREGP1HI:%[0-9]+]]:_(s32) = COPY $r3
; LITTLE: [[VREGP1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP1LO]](s32), [[VREGP1HI]](s32)
; BIG: [[VREGP1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP1HI]](s32), [[VREGP1LO]](s32)
; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
; CHECK: [[VREGP5:%[0-9]+]]:_(s64) = G_LOAD [[FIP5]](p0){{.*}}load 8
; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGP5]]
; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; CHECK-DAG: $r0 = COPY [[VREGVLO]]
; CHECK-DAG: $r1 = COPY [[VREGVHI]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
entry:
%v = fadd double %p1, %p5
ret double %v
}
define arm_aapcs_vfpcc double @test_double_gap_vfpcc(double %p0, float %filler,
double %p1, double %p2,
double %p3, double %p4,
double %reasonable,
double %parameters,
double %q0, double %q1) {
; CHECK-LABEL: name: test_double_gap_vfpcc
; CHECK: fixedStack:
; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
; CHECK: liveins: $d0, $d2, $d3, $d4, $d5, $d6, $d7, $s2
; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = COPY $d2
; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
; CHECK: [[VREGQ1:%[0-9]+]]:_(s64) = G_LOAD [[FIQ1]](p0){{.*}}load 8
; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGQ1]]
; CHECK: $d0 = COPY [[VREGV]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $d0
entry:
%v = fadd double %p1, %q1
ret double %v
}
define arm_aapcscc double @test_double_gap_aapcscc(float %filler, double %p0,
double %p1) {
; CHECK-LABEL: name: test_double_gap_aapcscc
; CHECK: fixedStack:
; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
; CHECK: liveins: $r0, $r2, $r3
; CHECK-DAG: [[VREGP0LO:%[0-9]+]]:_(s32) = COPY $r2
; CHECK-DAG: [[VREGP0HI:%[0-9]+]]:_(s32) = COPY $r3
; LITTLE: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0LO]](s32), [[VREGP0HI]](s32)
; BIG: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0HI]](s32), [[VREGP0LO]](s32)
; CHECK: [[FIP1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = G_LOAD [[FIP1]](p0){{.*}}load 8
; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP0]], [[VREGP1]]
; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; CHECK-DAG: $r0 = COPY [[VREGVLO]]
; CHECK-DAG: $r1 = COPY [[VREGVHI]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
entry:
%v = fadd double %p0, %p1
ret double %v
}
define arm_aapcscc double @test_double_gap2_aapcscc(double %p0, float %filler,
double %p1) {
; CHECK-LABEL: name: test_double_gap2_aapcscc
; CHECK: fixedStack:
; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
; CHECK: liveins: $r0, $r1, $r2
; CHECK-DAG: [[VREGP0LO:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[VREGP0HI:%[0-9]+]]:_(s32) = COPY $r1
; LITTLE: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0LO]](s32), [[VREGP0HI]](s32)
; BIG: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0HI]](s32), [[VREGP0LO]](s32)
; CHECK: [[FIP1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = G_LOAD [[FIP1]](p0){{.*}}load 8
; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP0]], [[VREGP1]]
; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
; CHECK-DAG: $r0 = COPY [[VREGVLO]]
; CHECK-DAG: $r1 = COPY [[VREGVHI]]
; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
entry:
%v = fadd double %p0, %p1
ret double %v
}
define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
%res = extractelement <2 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_s32_s32_s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_s32_s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK: [[VEC:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <1 x i32> zeroinitializer
%res = extractelement <1 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_v2s32_v3s32(i32 %arg1, i32 %arg2) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
%shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
%res = extractelement <3 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_v2s32_v4s32(i32 %arg1, i32 %arg2) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(0, 0, 0, 0)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<4 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
%shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <4 x i32> zeroinitializer
%res = extractelement <4 x i32> %shuffle, i32 0
ret i32 %res
}
define i32 @test_shufflevector_v4s32_v2s32(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) {
; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $r2
; CHECK: [[ARG4:%[0-9]+]]:_(s32) = COPY $r3
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK-DAG: [[V1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK-DAG: [[V3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V2]], [[ARG3]](s32), [[C2]](s32)
; CHECK-DAG: [[V4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V3]], [[ARG4]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[V4]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%v1 = insertelement <4 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <4 x i32> %v1, i32 %arg2, i32 1
%v3 = insertelement <4 x i32> %v2, i32 %arg3, i32 2
%v4 = insertelement <4 x i32> %v3, i32 %arg4, i32 3
%shuffle = shufflevector <4 x i32> %v4, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
%res = extractelement <2 x i32> %shuffle, i32 0
ret i32 %res
}
%struct.v2s32 = type { <2 x i32> }
define i32 @test_constantstruct_v2s32() {
; CHECK-LABEL: name: test_constantstruct_v2s32
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[C3]]
%vec = extractvalue %struct.v2s32 {<2 x i32><i32 1, i32 2>}, 0
%elt = extractelement <2 x i32> %vec, i32 0
ret i32 %elt
}
%struct.v2s32.s32.s32 = type { <2 x i32>, i32, i32 }
define i32 @test_constantstruct_v2s32_s32_s32() {
; CHECK-LABEL: name: test_constantstruct_v2s32_s32_s32
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[C5]](s32)
%vec = extractvalue %struct.v2s32.s32.s32 {<2 x i32><i32 1, i32 2>, i32 3, i32 4}, 0
%elt = extractelement <2 x i32> %vec, i32 0
ret i32 %elt
}
define void @test_load_store_struct({i32, i32} *%addr) {
; Make sure the IRTranslator doesn't use an unnecessarily large GEP index type
; when breaking up loads and stores of aggregates.
; CHECK-LABEL: name: test_load_store_struct
; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
; CHECK-DAG: [[VAL1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4 from %ir.addr)
; CHECK-DAG: [[OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR1]], [[OFFSET]](s32)
; CHECK-DAG: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4 from %ir.addr + 4)
; CHECK-DAG: G_STORE [[VAL1]](s32), [[ADDR1]](p0) :: (store 4 into %ir.addr)
; CHECK-DAG: [[ADDR3:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
; CHECK-DAG: G_STORE [[VAL2]](s32), [[ADDR3]](p0) :: (store 4 into %ir.addr + 4)
%val = load {i32, i32}, {i32, i32} *%addr, align 4
store {i32, i32} %val, {i32, i32} *%addr, align 4
ret void
}