1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00
llvm-mirror/test/CodeGen/ARM/fp16-no-condition.ll
Simon Tatham fb51a50eef [ARM] Make fullfp16 instructions not conditionalisable.
More or less all the instructions defined in the v8.2a full-fp16
extension are defined as UNPREDICTABLE if you put them in an IT block
(Thumb) or use with any condition other than AL (ARM). LLVM didn't
know that, and was happy to conditionalise them.

In order to force these instructions to count as not predicable, I had
to make a small Tablegen change. The code generation back end mostly
decides if an instruction was predicable by looking for something it
can identify as a predicate operand; there's an isPredicable bit flag
that overrides that check in the positive direction, but nothing that
overrides it in the negative direction.

(I considered the alternative approach of actually removing the
predicate operand from those instructions, but thought that it would
be more painful overall for instructions differing only in data type
to have different shapes of operand list. This way, the only code that
has to notice the difference is the if-converter.)

So I've added an isUnpredicable bit alongside isPredicable, and set
that bit on the right subset of FP16 instructions, and also on the
VSEL, VMAXNM/VMINNM and VRINT[ANPM] families which should be
unpredicable for all data types.

I've included a couple of representative regression tests, both of
which previously caused an fp16 instruction to be conditionalised in
ARM state and (with -arm-no-restrict-it) to be put in an IT block in
Thumb.

Reviewers: SjoerdMeijer, t.p.northover, efriedma

Reviewed By: efriedma

Subscribers: jdoerfert, javed.absar, kristof.beyls, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D57823

llvm-svn: 354768
2019-02-25 10:39:53 +00:00

101 lines
2.6 KiB
LLVM

; RUN: llc -O3 -mtriple=armv8a-none-eabi -mattr=+fullfp16 -o - %s | FileCheck %s
; RUN: llc -O3 -mtriple=thumbv8a-none-eabi -mattr=+fullfp16 -arm-no-restrict-it -o - %s | FileCheck %s
; Require the vmul.f16 not to be predicated, because it's illegal to
; do so with fp16 instructions
define half @conditional_fmul_f16(half* %p) {
; CHECK-LABEL: conditional_fmul_f16:
; CHECK: vmul.f16
entry:
%p1 = getelementptr half, half* %p, i32 1
%a = load half, half* %p, align 2
%threshold = load half, half* %p1, align 2
%flag = fcmp ogt half %a, %threshold
br i1 %flag, label %mul, label %out
mul:
%p2 = getelementptr half, half* %p, i32 2
%mult = load half, half* %p2, align 2
%b = fmul half %a, %mult
br label %out
out:
%sel = phi half [ %a, %entry ], [ %b, %mul ]
ret half %sel
}
; Expect that the corresponding vmul.f32 _will_ be predicated (to make
; sure the previous test is really testing something)
define float @conditional_fmul_f32(float* %p) {
; CHECK-LABEL: conditional_fmul_f32:
; CHECK: vmulgt.f32
entry:
%p1 = getelementptr float, float* %p, i32 1
%a = load float, float* %p, align 2
%threshold = load float, float* %p1, align 2
%flag = fcmp ogt float %a, %threshold
br i1 %flag, label %mul, label %out
mul:
%p2 = getelementptr float, float* %p, i32 2
%mult = load float, float* %p2, align 2
%b = fmul float %a, %mult
br label %out
out:
%sel = phi float [ %a, %entry ], [ %b, %mul ]
ret float %sel
}
; Require the two comparisons to be done with unpredicated vcmp.f16
; instructions (again, it is illegal to predicate them)
define void @chained_comparisons_f16(half* %p) {
; CHECK-LABEL: chained_comparisons_f16:
; CHECK: vcmp.f16
; CHECK: vcmp.f16
entry:
%p1 = getelementptr half, half* %p, i32 1
%a = load half, half* %p, align 2
%b = load half, half* %p1, align 2
%aflag = fcmp oeq half %a, 0xH0000
%bflag = fcmp oeq half %b, 0xH0000
%flag = or i1 %aflag, %bflag
br i1 %flag, label %call, label %out
call:
call void @external_function()
br label %out
out:
ret void
}
; Again, do the corresponding test with 32-bit floats and check that
; the second comparison _is_ predicated on the result of the first.
define void @chained_comparisons_f32(float* %p) {
; CHECK-LABEL: chained_comparisons_f32:
; CHECK: vcmp.f32
; CHECK: vcmpne.f32
entry:
%p1 = getelementptr float, float* %p, i32 1
%a = load float, float* %p, align 2
%b = load float, float* %p1, align 2
%aflag = fcmp oeq float %a, 0x00000000
%bflag = fcmp oeq float %b, 0x00000000
%flag = or i1 %aflag, %bflag
br i1 %flag, label %call, label %out
call:
call void @external_function()
br label %out
out:
ret void
}
declare void @external_function()