diff options
| author | Diana Picus <diana.picus@linaro.org> | 2017-07-07 08:39:04 +0000 |
|---|---|---|
| committer | Diana Picus <diana.picus@linaro.org> | 2017-07-07 08:39:04 +0000 |
| commit | 5b9165384023c5ac3c2727ecece3dfd5c74876e2 (patch) | |
| tree | e80150302548eefaae17bb85c11c20b021ef0c4a /llvm/test/CodeGen | |
| parent | 85e9216e8c30323d62a727af0d956df10513d3db (diff) | |
| download | bcm5719-llvm-5b9165384023c5ac3c2727ecece3dfd5c74876e2.tar.gz bcm5719-llvm-5b9165384023c5ac3c2727ecece3dfd5c74876e2.zip | |
[ARM] GlobalISel: Select hard G_FCMP for s32
We lower to a sequence consisting of:
- MOVi 0 into a register
- VCMPS to do the actual comparison and set the VFP flags
- FMSTAT to move the flags out of the VFP unit
- MOVCCi to either use the "zero register" that we have previously set
with the MOVi, or move 1 into the result register, based on the values
of the flags
As was the case with soft-float, for some predicates (one, ueq) we
actually need two comparisons instead of just one. When that happens, we
generate two VCMPS-FMSTAT-MOVCCi sequences and chain them by means of
using the result of the first MOVCCi as the "zero register" for the
second one. This is a bit overkill, since one comparison followed by
two non-flag-setting conditional moves should be enough. In any case,
the backend manages to CSE one of the comparisons away so it doesn't
matter much.
Note that unlike SelectionDAG and FastISel, we always use VCMPS, and not
VCMPES. This makes the code a lot simpler, and it also seems correct
since the LLVM Lang Ref defines simple true/false returns if the
operands are QNaN's. For SNaN's, even VCMPS throws an Invalid Operand
exception, so they won't be slipping through unnoticed.
Implementation-wise, this introduces a template so we can share the same
code that we use for handling integer comparisons, since the only
differences are in the details (exact opcodes to be used etc). Hopefully
this will be easy to extend to s64 G_FCMP.
llvm-svn: 307365
Diffstat (limited to 'llvm/test/CodeGen')
| -rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select-cmp.mir | 607 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll | 30 |
2 files changed, 637 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select-cmp.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select-cmp.mir index 111375ece51..010fd778c03 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select-cmp.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select-cmp.mir @@ -10,6 +10,27 @@ define void @test_icmp_sge_s32() { ret void } define void @test_icmp_slt_s32() { ret void } define void @test_icmp_sle_s32() { ret void } + + define void @test_fcmp_true_s32() #0 { ret void } + define void @test_fcmp_false_s32() #0 { ret void } + + define void @test_fcmp_oeq_s32() #0 { ret void } + define void @test_fcmp_ogt_s32() #0 { ret void } + define void @test_fcmp_oge_s32() #0 { ret void } + define void @test_fcmp_olt_s32() #0 { ret void } + define void @test_fcmp_ole_s32() #0 { ret void } + define void @test_fcmp_ord_s32() #0 { ret void } + define void @test_fcmp_ugt_s32() #0 { ret void } + define void @test_fcmp_uge_s32() #0 { ret void } + define void @test_fcmp_ult_s32() #0 { ret void } + define void @test_fcmp_ule_s32() #0 { ret void } + define void @test_fcmp_une_s32() #0 { ret void } + define void @test_fcmp_uno_s32() #0 { ret void } + + define void @test_fcmp_one_s32() #0 { ret void } + define void @test_fcmp_ueq_s32() #0 { ret void } + + attributes #0 = { "target-features"="+vfp2" } ... --- name: test_icmp_eq_s32 @@ -371,3 +392,589 @@ body: | BX_RET 14, _, implicit %r0 ; CHECK: BX_RET 14, _, implicit %r0 ... +--- +name: test_fcmp_true_s32 +# CHECK-LABEL: name: test_fcmp_true_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + %1(s32) = COPY %s1 + + %2(s1) = G_FCMP floatpred(true), %0(s32), %1 + ; CHECK: [[RES:%[0-9]+]] = MOVi 1, 14, _, _ + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_false_s32 +# CHECK-LABEL: name: test_fcmp_false_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + %1(s32) = COPY %s1 + + %2(s1) = G_FCMP floatpred(false), %0(s32), %1 + ; CHECK: [[RES:%[0-9]+]] = MOVi 0, 14, _, _ + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_oeq_s32 +# CHECK-LABEL: name: test_fcmp_oeq_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(oeq), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 0, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ogt_s32 +# CHECK-LABEL: name: test_fcmp_ogt_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ogt), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 12, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_oge_s32 +# CHECK-LABEL: name: test_fcmp_oge_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(oge), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 10, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_olt_s32 +# CHECK-LABEL: name: test_fcmp_olt_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(olt), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 4, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ole_s32 +# CHECK-LABEL: name: test_fcmp_ole_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ole), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 9, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ord_s32 +# CHECK-LABEL: name: test_fcmp_ord_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ord), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 7, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ugt_s32 +# CHECK-LABEL: name: test_fcmp_ugt_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ugt), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 8, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_uge_s32 +# CHECK-LABEL: name: test_fcmp_uge_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(uge), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 5, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ult_s32 +# CHECK-LABEL: name: test_fcmp_ult_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ult), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 11, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ule_s32 +# CHECK-LABEL: name: test_fcmp_ule_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ule), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 13, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_une_s32 +# CHECK-LABEL: name: test_fcmp_une_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(une), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 1, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_uno_s32 +# CHECK-LABEL: name: test_fcmp_uno_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(uno), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[ZERO]], 1, 6, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_one_s32 +# CHECK-LABEL: name: test_fcmp_one_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(one), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES1:%[0-9]+]] = MOVCCi [[ZERO]], 1, 12, %cpsr + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[RES1]], 1, 4, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_fcmp_ueq_s32 +# CHECK-LABEL: name: test_fcmp_ueq_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } +body: | + bb.0: + liveins: %s0, %s1 + + %0(s32) = COPY %s0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0 + + %1(s32) = COPY %s1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1 + + %2(s1) = G_FCMP floatpred(ueq), %0(s32), %1 + ; CHECK: [[ZERO:%[0-9]+]] = MOVi 0, 14, _, _ + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES1:%[0-9]+]] = MOVCCi [[ZERO]], 1, 0, %cpsr + ; CHECK: VCMPS [[VREGX]], [[VREGY]], 14, _, implicit-def %fpscr_nzcv + ; CHECK: FMSTAT 14, _, implicit-def %cpsr, implicit %fpscr_nzcv + ; CHECK: [[RES:%[0-9]+]] = MOVCCi [[RES1]], 1, 6, %cpsr + + %3(s32) = G_ZEXT %2(s1) + ; CHECK: [[RET:%[0-9]+]] = ANDri [[RES]], 1, 14, _, _ + + %r0 = COPY %3(s32) + ; CHECK: %r0 = COPY [[RET]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll index 7d021fdb43d..98b39e444ac 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll @@ -49,3 +49,33 @@ define arm_aapcscc double @test_add_double(double %x, double %y) { %r = fadd double %x, %y ret double %r } + +define arm_aapcs_vfpcc i32 @test_cmp_float_ogt(float %x, float %y) { +; CHECK-LABEL: test_cmp_float_ogt +; HARD: vcmp.f32 +; HARD: vmrs APSR_nzcv, fpscr +; HARD-NEXT: movgt +; SOFT-AEABI: blx __aeabi_fcmpgt +; SOFT-DEFAULT: blx __gtsf2 +entry: + %v = fcmp ogt float %x, %y + %r = zext i1 %v to i32 + ret i32 %r +} + +define arm_aapcs_vfpcc i32 @test_cmp_float_one(float %x, float %y) { +; CHECK-LABEL: test_cmp_float_one +; HARD: vcmp.f32 +; HARD: vmrs APSR_nzcv, fpscr +; HARD: movgt +; HARD-NOT: vcmp +; HARD: movmi +; SOFT-AEABI-DAG: blx __aeabi_fcmpgt +; SOFT-AEABI-DAG: blx __aeabi_fcmplt +; SOFT-DEFAULT-DAG: blx __gtsf2 +; SOFT-DEFAULT-DAG: blx __ltsf2 +entry: + %v = fcmp one float %x, %y + %r = zext i1 %v to i32 + ret i32 %r +} |

