blob: 3309f36ed32cab4ea266c7eede695feb7274d990 [file]
; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
; Make sure the copysign intrinsic is expanded to bitwise operations.
; CHECK-LABEL: copysign_half
define noundef half @copysign_half(half noundef %a, half noundef %b) {
entry:
; CHECK: [[MAGNITUDE_INT:%.*]] = bitcast half %{{.*}} to i16
; CHECK: [[SIGN_INT:%.*]] = bitcast half %{{.*}} to i16
; CHECK: [[MAGNITUDE_BITS:%.*]] = and i16 [[MAGNITUDE_INT]], 32767
; CHECK: [[SIGN_BITS:%.*]] = and i16 [[SIGN_INT]], -32768
; CHECK: [[COMBINED_INT:%.*]] = or i16 [[MAGNITUDE_BITS]], [[SIGN_BITS]]
; CHECK: bitcast i16 [[COMBINED_INT]] to half
%r = call half @llvm.copysign.f16(half %a, half %b)
ret half %r
}
; CHECK-LABEL: copysign_float
define noundef float @copysign_float(float noundef %a, float noundef %b) {
entry:
; CHECK: [[MAGNITUDE_INT:%.*]] = bitcast float %{{.*}} to i32
; CHECK: [[SIGN_INT:%.*]] = bitcast float %{{.*}} to i32
; CHECK: [[MAGNITUDE_BITS:%.*]] = and i32 [[MAGNITUDE_INT]], 2147483647
; CHECK: [[SIGN_BITS:%.*]] = and i32 [[SIGN_INT]], -2147483648
; CHECK: [[COMBINED_INT:%.*]] = or i32 [[MAGNITUDE_BITS]], [[SIGN_BITS]]
; CHECK: bitcast i32 [[COMBINED_INT]] to float
%r = call float @llvm.copysign.f32(float %a, float %b)
ret float %r
}
; CHECK-LABEL: copysign_double
define noundef double @copysign_double(double noundef %a, double noundef %b) {
entry:
; CHECK: [[MAGNITUDE_HALVES:%.*]] = call %dx.types.splitdouble @dx.op.splitDouble.f64(i32 102, double %{{.*}})
; CHECK: [[SIGN_HALVES:%.*]] = call %dx.types.splitdouble @dx.op.splitDouble.f64(i32 102, double %{{.*}})
; CHECK: [[MAGNITUDE_LOW:%.*]] = extractvalue %dx.types.splitdouble [[MAGNITUDE_HALVES]], 0
; CHECK: [[MAGNITUDE_HIGH:%.*]] = extractvalue %dx.types.splitdouble [[MAGNITUDE_HALVES]], 1
; CHECK: [[SIGN_HIGH:%.*]] = extractvalue %dx.types.splitdouble [[SIGN_HALVES]], 1
; CHECK: [[MAGNITUDE_BITS:%.*]] = and i32 [[MAGNITUDE_HIGH]], 2147483647
; CHECK: [[SIGN_BITS:%.*]] = and i32 [[SIGN_HIGH]], -2147483648
; CHECK: [[COMBINED_HIGH:%.*]] = or i32 [[MAGNITUDE_BITS]], [[SIGN_BITS]]
; CHECK: call double @dx.op.makeDouble.f64(i32 101, i32 [[MAGNITUDE_LOW]], i32 [[COMBINED_HIGH]])
%r = call double @llvm.copysign.f64(double %a, double %b)
ret double %r
}
; CHECK-LABEL: copysign_float4
define noundef <4 x float> @copysign_float4(<4 x float> noundef %a, <4 x float> noundef %b) {
entry:
; CHECK: [[MAGNITUDE_INT:%.*]] = bitcast <4 x float> %{{.*}} to <4 x i32>
; CHECK: [[SIGN_INT:%.*]] = bitcast <4 x float> %{{.*}} to <4 x i32>
; CHECK: [[MAGNITUDE_BITS:%.*]] = and <4 x i32> [[MAGNITUDE_INT]], splat (i32 2147483647)
; CHECK: [[SIGN_BITS:%.*]] = and <4 x i32> [[SIGN_INT]], splat (i32 -2147483648)
; CHECK: [[COMBINED_INT:%.*]] = or <4 x i32> [[MAGNITUDE_BITS]], [[SIGN_BITS]]
; CHECK: bitcast <4 x i32> [[COMBINED_INT]] to <4 x float>
%r = call <4 x float> @llvm.copysign.v4f32(<4 x float> %a, <4 x float> %b)
ret <4 x float> %r
}
declare half @llvm.copysign.f16(half, half)
declare float @llvm.copysign.f32(float, float)
declare double @llvm.copysign.f64(double, double)
declare <4 x float> @llvm.copysign.v4f32(<4 x float>, <4 x float>)