1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/test/CodeGen/SystemZ/fp-strict-mul-12.ll
Ulrich Weigand c56f83f1a4 [SystemZ] Fix 128-bit strict FMA expansion pre-z14
Before z14, we did not have any FMA instruction for 128-bit
floating-point, so the @llvm.fma.f128 intrinsic needs to be
expanded to a libcall on those platforms.

This worked correctly for regular FMA, but was implemented
incorrectly for the strict version.  This was not noticed
because we did not have test coverage for this case.

This patch fixes that incorrect expansion and adds the
missing test cases.
2019-12-11 16:32:08 +01:00

87 lines
3.2 KiB
LLVM

; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare fp128 @llvm.experimental.constrained.fma.f128(fp128 %f1, fp128 %f2, fp128 %f3, metadata, metadata)
define void @f1(fp128 *%ptr1, fp128 *%ptr2, fp128 *%ptr3, fp128 *%dst) #0 {
; CHECK-LABEL: f1:
; CHECK-DAG: vl [[REG1:%v[0-9]+]], 0(%r2)
; CHECK-DAG: vl [[REG2:%v[0-9]+]], 0(%r3)
; CHECK-DAG: vl [[REG3:%v[0-9]+]], 0(%r4)
; CHECK: wfmaxb [[RES:%v[0-9]+]], [[REG1]], [[REG2]], [[REG3]]
; CHECK: vst [[RES]], 0(%r5)
; CHECK: br %r14
%f1 = load fp128, fp128 *%ptr1
%f2 = load fp128, fp128 *%ptr2
%f3 = load fp128, fp128 *%ptr3
%res = call fp128 @llvm.experimental.constrained.fma.f128 (
fp128 %f1, fp128 %f2, fp128 %f3,
metadata !"round.dynamic",
metadata !"fpexcept.strict") #0
store fp128 %res, fp128 *%dst
ret void
}
define void @f2(fp128 *%ptr1, fp128 *%ptr2, fp128 *%ptr3, fp128 *%dst) #0 {
; CHECK-LABEL: f2:
; CHECK-DAG: vl [[REG1:%v[0-9]+]], 0(%r2)
; CHECK-DAG: vl [[REG2:%v[0-9]+]], 0(%r3)
; CHECK-DAG: vl [[REG3:%v[0-9]+]], 0(%r4)
; CHECK: wfmsxb [[RES:%v[0-9]+]], [[REG1]], [[REG2]], [[REG3]]
; CHECK: vst [[RES]], 0(%r5)
; CHECK: br %r14
%f1 = load fp128, fp128 *%ptr1
%f2 = load fp128, fp128 *%ptr2
%f3 = load fp128, fp128 *%ptr3
%neg = fsub fp128 0xL00000000000000008000000000000000, %f3
%res = call fp128 @llvm.experimental.constrained.fma.f128 (
fp128 %f1, fp128 %f2, fp128 %neg,
metadata !"round.dynamic",
metadata !"fpexcept.strict") #0
store fp128 %res, fp128 *%dst
ret void
}
define void @f3(fp128 *%ptr1, fp128 *%ptr2, fp128 *%ptr3, fp128 *%dst) #0 {
; CHECK-LABEL: f3:
; CHECK-DAG: vl [[REG1:%v[0-9]+]], 0(%r2)
; CHECK-DAG: vl [[REG2:%v[0-9]+]], 0(%r3)
; CHECK-DAG: vl [[REG3:%v[0-9]+]], 0(%r4)
; CHECK: wfnmaxb [[RES:%v[0-9]+]], [[REG1]], [[REG2]], [[REG3]]
; CHECK: vst [[RES]], 0(%r5)
; CHECK: br %r14
%f1 = load fp128, fp128 *%ptr1
%f2 = load fp128, fp128 *%ptr2
%f3 = load fp128, fp128 *%ptr3
%res = call fp128 @llvm.experimental.constrained.fma.f128 (
fp128 %f1, fp128 %f2, fp128 %f3,
metadata !"round.dynamic",
metadata !"fpexcept.strict") #0
%negres = fsub fp128 0xL00000000000000008000000000000000, %res
store fp128 %negres, fp128 *%dst
ret void
}
define void @f4(fp128 *%ptr1, fp128 *%ptr2, fp128 *%ptr3, fp128 *%dst) #0 {
; CHECK-LABEL: f4:
; CHECK-DAG: vl [[REG1:%v[0-9]+]], 0(%r2)
; CHECK-DAG: vl [[REG2:%v[0-9]+]], 0(%r3)
; CHECK-DAG: vl [[REG3:%v[0-9]+]], 0(%r4)
; CHECK: wfnmsxb [[RES:%v[0-9]+]], [[REG1]], [[REG2]], [[REG3]]
; CHECK: vst [[RES]], 0(%r5)
; CHECK: br %r14
%f1 = load fp128, fp128 *%ptr1
%f2 = load fp128, fp128 *%ptr2
%f3 = load fp128, fp128 *%ptr3
%neg = fsub fp128 0xL00000000000000008000000000000000, %f3
%res = call fp128 @llvm.experimental.constrained.fma.f128 (
fp128 %f1, fp128 %f2, fp128 %neg,
metadata !"round.dynamic",
metadata !"fpexcept.strict") #0
%negres = fsub fp128 0xL00000000000000008000000000000000, %res
store fp128 %negres, fp128 *%dst
ret void
}
attributes #0 = { strictfp }