[llvm] 9ef1333 - AMDGPU: Replace certain llvm.amdgcn.class uses with llvm.is.fpclass
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed May 24 13:57:27 PDT 2023
Author: Matt Arsenault
Date: 2023-05-24T21:49:52+01:00
New Revision: 9ef1333bf48eb66a6cfde19e926044fff2a2e7a8
URL: https://github.com/llvm/llvm-project/commit/9ef1333bf48eb66a6cfde19e926044fff2a2e7a8
DIFF: https://github.com/llvm/llvm-project/commit/9ef1333bf48eb66a6cfde19e926044fff2a2e7a8.diff
LOG: AMDGPU: Replace certain llvm.amdgcn.class uses with llvm.is.fpclass
Most transforms should now be performed on llvm.is.fpclass. Unlike the
generic intrinsic, this supports variable test masks.
Added:
Modified:
llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index 116574c289dc2..e49a480c0ea46 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -450,86 +450,25 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
Value *Src0 = II.getArgOperand(0);
Value *Src1 = II.getArgOperand(1);
const ConstantInt *CMask = dyn_cast<ConstantInt>(Src1);
- if (!CMask) {
- if (isa<UndefValue>(Src0)) {
- return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
- }
+ if (CMask) {
+ II.setCalledOperand(Intrinsic::getDeclaration(
+ II.getModule(), Intrinsic::is_fpclass, Src0->getType()));
- if (isa<UndefValue>(Src1)) {
- return IC.replaceInstUsesWith(II,
- ConstantInt::get(II.getType(), false));
- }
- break;
+ // Clamp any excess bits, as they're illegal for the generic intrinsic.
+ II.setArgOperand(1, ConstantInt::get(Src1->getType(),
+ CMask->getZExtValue() & fcAllFlags));
+ return &II;
}
- uint32_t Mask = CMask->getZExtValue();
-
- // If all tests are made, it doesn't matter what the value is.
- if ((Mask & fcAllFlags) == fcAllFlags) {
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), true));
- }
+ // FIXME: Should propagate poison.
+ if (isa<UndefValue>(Src0))
+ return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
- if ((Mask & fcAllFlags) == 0) {
+ if (isa<UndefValue>(Src1)) {
return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), false));
}
- if (Mask == fcNan && !II.isStrictFP()) {
- // Equivalent of isnan. Replace with standard fcmp.
- Value *FCmp = IC.Builder.CreateFCmpUNO(Src0, Src0);
- FCmp->takeName(&II);
- return IC.replaceInstUsesWith(II, FCmp);
- }
-
- if (Mask == fcZero && !II.isStrictFP()) {
- // Equivalent of == 0.
- Value *FCmp =
- IC.Builder.CreateFCmpOEQ(Src0, ConstantFP::get(Src0->getType(), 0.0));
-
- FCmp->takeName(&II);
- return IC.replaceInstUsesWith(II, FCmp);
- }
-
- // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other
- if ((Mask & fcNan) &&
- isKnownNeverNaN(Src0, IC.getDataLayout(), &IC.getTargetLibraryInfo())) {
- return IC.replaceOperand(
- II, 1, ConstantInt::get(Src1->getType(), Mask & ~fcNan));
- }
-
- const ConstantFP *CVal = dyn_cast<ConstantFP>(Src0);
- if (!CVal) {
- if (isa<UndefValue>(Src0)) {
- return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
- }
-
- // Clamp mask to used bits
- if ((Mask & fcAllFlags) != Mask) {
- CallInst *NewCall = IC.Builder.CreateCall(
- II.getCalledFunction(),
- {Src0, ConstantInt::get(Src1->getType(), Mask & fcAllFlags)});
-
- NewCall->takeName(&II);
- return IC.replaceInstUsesWith(II, NewCall);
- }
-
- break;
- }
-
- const APFloat &Val = CVal->getValueAPF();
-
- bool Result =
- ((Mask & fcSNan) && Val.isNaN() && Val.isSignaling()) ||
- ((Mask & fcQNan) && Val.isNaN() && !Val.isSignaling()) ||
- ((Mask & fcNegInf) && Val.isInfinity() && Val.isNegative()) ||
- ((Mask & fcNegNormal) && Val.isNormal() && Val.isNegative()) ||
- ((Mask & fcNegSubnormal) && Val.isDenormal() && Val.isNegative()) ||
- ((Mask & fcNegZero) && Val.isZero() && Val.isNegative()) ||
- ((Mask & fcPosZero) && Val.isZero() && !Val.isNegative()) ||
- ((Mask & fcPosSubnormal) && Val.isDenormal() && !Val.isNegative()) ||
- ((Mask & fcPosNormal) && Val.isNormal() && !Val.isNegative()) ||
- ((Mask & fcPosInf) && Val.isInfinity() && !Val.isNegative());
-
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), Result));
+ break;
}
case Intrinsic::amdgcn_cvt_pkrtz: {
Value *Src0 = II.getArgOperand(0);
diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
index 133223fea7664..522fe70b157e2 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
@@ -592,7 +592,7 @@ define i1 @test_class_poison_val_f32(i32 %arg) nounwind {
define i1 @test_class_over_max_mask_f32(float %x) nounwind {
; CHECK-LABEL: @test_class_over_max_mask_f32(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.amdgcn.class.f32(float [[X:%.*]], i32 1)
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 1)
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.amdgcn.class.f32(float %x, i32 1025)
@@ -675,7 +675,7 @@ define i1 @test_class_isnan_f32(float %x) nounwind {
define i1 @test_class_isnan_f32_strict(float %x) nounwind {
; CHECK-LABEL: @test_class_isnan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.amdgcn.class.f32(float [[X:%.*]], i32 3) #[[ATTR15:[0-9]+]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3) #[[ATTR15:[0-9]+]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.amdgcn.class.f32(float %x, i32 3) strictfp
@@ -693,7 +693,7 @@ define i1 @test_class_is_p0_n0_f32(float %x) nounwind {
define i1 @test_class_is_p0_n0_f32_strict(float %x) nounwind {
; CHECK-LABEL: @test_class_is_p0_n0_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.amdgcn.class.f32(float [[X:%.*]], i32 96) #[[ATTR15]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 96) #[[ATTR15]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.amdgcn.class.f32(float %x, i32 96) strictfp
@@ -914,7 +914,7 @@ define i1 @test_class_is_nan_nnan_src(float %x) {
define i1 @test_class_is_nan_other_nnan_src(float %x) {
; CHECK-LABEL: @test_class_is_nan_other_nnan_src(
; CHECK-NEXT: [[NNAN:%.*]] = fadd nnan float [[X:%.*]], 1.000000e+00
-; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.amdgcn.class.f32(float [[NNAN]], i32 264)
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[NNAN]], i32 264)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%nnan = fadd nnan float %x, 1.0
More information about the llvm-commits
mailing list