When floating-point operations are legalized to operations of a higher precision (e.g. f16 fadd being legalized to f32 fadd) then we get narrowing then widening operations between each operation. With the appropriate fast math flags (nnan ninf contract) we can eliminate these casts.
200 lines
11 KiB
LLVM
200 lines
11 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc < %s -mtriple=aarch64 -mattr=-fullfp16 -stop-after=finalize-isel | FileCheck %s --check-prefixes=CHECK-CVT
|
|
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 -stop-after=finalize-isel | FileCheck %s --check-prefixes=CHECK-FP16
|
|
|
|
; Check that the output instructions have the same fast math flags as the input
|
|
; fadd, even when fadd is promoted to float type.
|
|
|
|
define half @normal_fadd(half %x, half %y) {
|
|
; CHECK-CVT-LABEL: name: normal_fadd
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = nofpexcept FCVTHSr killed [[FADDSrr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: normal_fadd
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = nofpexcept FADDHrr [[COPY1]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add = fadd half %x, %y
|
|
ret half %add
|
|
}
|
|
|
|
define half @fast_fadd(half %x, half %y) {
|
|
; CHECK-CVT-LABEL: name: fast_fadd
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = nnan ninf nsz arcp contract afn reassoc nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = nnan ninf nsz arcp contract afn reassoc nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nnan ninf nsz arcp contract afn reassoc nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = nnan ninf nsz arcp contract afn reassoc nofpexcept FCVTHSr killed [[FADDSrr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: fast_fadd
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = nnan ninf nsz arcp contract afn reassoc nofpexcept FADDHrr [[COPY1]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add = fadd fast half %x, %y
|
|
ret half %add
|
|
}
|
|
|
|
define half @ninf_fadd(half %x, half %y) {
|
|
; CHECK-CVT-LABEL: name: ninf_fadd
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = ninf nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = ninf nofpexcept FCVTHSr killed [[FADDSrr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: ninf_fadd
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = ninf nofpexcept FADDHrr [[COPY1]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add = fadd ninf half %x, %y
|
|
ret half %add
|
|
}
|
|
|
|
; Check that when we have the right fast math flags the converts in between the
|
|
; two fadds are removed.
|
|
|
|
define half @normal_fadd_sequence(half %x, half %y, half %z) {
|
|
; CHECK-CVT-LABEL: name: normal_fadd_sequence
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr [[COPY2]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = nofpexcept FCVTHSr killed [[FADDSrr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr2:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr killed [[FCVTHSr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr3:%[0-9]+]]:fpr32 = nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr1:%[0-9]+]]:fpr32 = nofpexcept FADDSrr killed [[FCVTSHr2]], killed [[FCVTSHr3]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr1:%[0-9]+]]:fpr16 = nofpexcept FCVTHSr killed [[FADDSrr1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr1]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: normal_fadd_sequence
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = nofpexcept FADDHrr [[COPY2]], [[COPY1]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: [[FADDHrr1:%[0-9]+]]:fpr16 = nofpexcept FADDHrr killed [[FADDHrr]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr1]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add1 = fadd half %x, %y
|
|
%add2 = fadd half %add1, %z
|
|
ret half %add2
|
|
}
|
|
|
|
define half @nnan_ninf_contract_fadd_sequence(half %x, half %y, half %z) {
|
|
; CHECK-CVT-LABEL: name: nnan_ninf_contract_fadd_sequence
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = nnan ninf contract nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = nnan ninf contract nofpexcept FCVTSHr [[COPY2]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nnan ninf contract nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr2:%[0-9]+]]:fpr32 = nnan ninf contract nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr1:%[0-9]+]]:fpr32 = nnan ninf contract nofpexcept FADDSrr killed [[FADDSrr]], killed [[FCVTSHr2]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = nnan ninf contract nofpexcept FCVTHSr killed [[FADDSrr1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: nnan_ninf_contract_fadd_sequence
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = nnan ninf contract nofpexcept FADDHrr [[COPY2]], [[COPY1]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: [[FADDHrr1:%[0-9]+]]:fpr16 = nnan ninf contract nofpexcept FADDHrr killed [[FADDHrr]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr1]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add1 = fadd nnan ninf contract half %x, %y
|
|
%add2 = fadd nnan ninf contract half %add1, %z
|
|
ret half %add2
|
|
}
|
|
|
|
define half @ninf_fadd_sequence(half %x, half %y, half %z) {
|
|
; CHECK-CVT-LABEL: name: ninf_fadd_sequence
|
|
; CHECK-CVT: bb.0.entry:
|
|
; CHECK-CVT-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-CVT-NEXT: {{ $}}
|
|
; CHECK-CVT-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-CVT-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-CVT-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-CVT-NEXT: [[FCVTSHr:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr [[COPY1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr1:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr [[COPY2]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = ninf nofpexcept FADDSrr killed [[FCVTSHr1]], killed [[FCVTSHr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = ninf nofpexcept FCVTHSr killed [[FADDSrr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr2:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr killed [[FCVTHSr]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTSHr3:%[0-9]+]]:fpr32 = ninf nofpexcept FCVTSHr [[COPY]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FADDSrr1:%[0-9]+]]:fpr32 = ninf nofpexcept FADDSrr killed [[FCVTSHr2]], killed [[FCVTSHr3]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: [[FCVTHSr1:%[0-9]+]]:fpr16 = ninf nofpexcept FCVTHSr killed [[FADDSrr1]], implicit $fpcr
|
|
; CHECK-CVT-NEXT: $h0 = COPY [[FCVTHSr1]]
|
|
; CHECK-CVT-NEXT: RET_ReallyLR implicit $h0
|
|
;
|
|
; CHECK-FP16-LABEL: name: ninf_fadd_sequence
|
|
; CHECK-FP16: bb.0.entry:
|
|
; CHECK-FP16-NEXT: liveins: $h0, $h1, $h2
|
|
; CHECK-FP16-NEXT: {{ $}}
|
|
; CHECK-FP16-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $h2
|
|
; CHECK-FP16-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $h1
|
|
; CHECK-FP16-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $h0
|
|
; CHECK-FP16-NEXT: [[FADDHrr:%[0-9]+]]:fpr16 = ninf nofpexcept FADDHrr [[COPY2]], [[COPY1]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: [[FADDHrr1:%[0-9]+]]:fpr16 = ninf nofpexcept FADDHrr killed [[FADDHrr]], [[COPY]], implicit $fpcr
|
|
; CHECK-FP16-NEXT: $h0 = COPY [[FADDHrr1]]
|
|
; CHECK-FP16-NEXT: RET_ReallyLR implicit $h0
|
|
entry:
|
|
%add1 = fadd ninf half %x, %y
|
|
%add2 = fadd ninf half %add1, %z
|
|
ret half %add2
|
|
}
|