| ; 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>) |