diff --git a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll new file mode 100644 index 000000000000..babd1c68f161 --- /dev/null +++ b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll @@ -0,0 +1,130 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -S -passes=attributor -attributor-manifest-internal < %s | FileCheck %s + +declare float @llvm.amdgcn.exp2.f32(float) + +define half @ret_exp_f16(half %arg0) { +; CHECK-LABEL: define half @ret_exp_f16( +; CHECK-SAME: half [[ARG0:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.amdgcn.exp2.f16(half [[ARG0]]) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: ret half [[CALL]] +; + %call = call half @llvm.amdgcn.exp2.f16(half %arg0) + ret half %call +} + +define float @ret_exp_f32(float %arg0) { +; CHECK-LABEL: define float @ret_exp_f32( +; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_noinf(float nofpclass(inf) %arg0) { +; CHECK-LABEL: define float @ret_exp_noinf( +; CHECK-SAME: float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_nopinf(float nofpclass(pinf) %arg0) { +; CHECK-LABEL: define float @ret_exp_nopinf( +; CHECK-SAME: float nofpclass(pinf) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_noninf(float nofpclass(ninf) %arg0) { +; CHECK-LABEL: define float @ret_exp_noninf( +; CHECK-SAME: float nofpclass(ninf) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_nonan(float nofpclass(nan) %arg0) { +; CHECK-LABEL: define float @ret_exp_nonan( +; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_nonan_noinf(float nofpclass(nan inf) %arg0) { +; CHECK-LABEL: define float @ret_exp_nonan_noinf( +; CHECK-SAME: float nofpclass(nan inf) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0) { +; CHECK-LABEL: define float @ret_exp_nonan_noinf_nozero( +; CHECK-SAME: float nofpclass(nan inf zero) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf zero) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_noinf_nozero(float nofpclass(inf zero) %arg0) { +; CHECK-LABEL: define float @ret_exp_noinf_nozero( +; CHECK-SAME: float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_noinf_nonegzero(float nofpclass(inf nzero) %arg0) { +; CHECK-LABEL: define float @ret_exp_noinf_nonegzero( +; CHECK-SAME: float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = call float @llvm.amdgcn.exp2.f32(float %arg0) + ret float %call +} + +define float @ret_exp_positive_source(i32 %arg) { +; CHECK-LABEL: define float @ret_exp_positive_source( +; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[UITOFP:%.*]] = uitofp i32 [[ARG]] to float +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[UITOFP]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %uitofp = uitofp i32 %arg to float + %call = call float @llvm.amdgcn.exp2.f32(float %uitofp) + ret float %call +} + +; Could produce a nan because we don't know if the multiply is negative. +define float @ret_exp_unknown_sign(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) { +; CHECK-LABEL: define float @ret_exp_unknown_sign( +; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[UNKNOWN_SIGN_NOT_NAN:%.*]] = fmul nnan float [[ARG0]], [[ARG1]] +; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[UNKNOWN_SIGN_NOT_NAN]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %unknown.sign.not.nan = fmul nnan float %arg0, %arg1 + %call = call float @llvm.amdgcn.exp2.f32(float %unknown.sign.not.nan) + ret float %call +} +