[llvm] c6aaa0b - AMDGPU: Perform basic folds on llvm.amdgcn.exp2

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 15 04:02:43 PDT 2023


Author: Matt Arsenault
Date: 2023-06-15T07:01:06-04:00
New Revision: c6aaa0b14f2ab7ed764cd494a605f30a9e02c40b

URL: https://github.com/llvm/llvm-project/commit/c6aaa0b14f2ab7ed764cd494a605f30a9e02c40b
DIFF: https://github.com/llvm/llvm-project/commit/c6aaa0b14f2ab7ed764cd494a605f30a9e02c40b.diff

LOG: AMDGPU: Perform basic folds on llvm.amdgcn.exp2

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 1f6d2f541adc8..c215ee33b5237 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -449,7 +449,10 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
 
     break;
   }
-  case Intrinsic::amdgcn_log: {
+  case Intrinsic::amdgcn_log:
+  case Intrinsic::amdgcn_exp2: {
+    const bool IsLog = IID == Intrinsic::amdgcn_log;
+    const bool IsExp = IID == Intrinsic::amdgcn_exp2;
     Value *Src = II.getArgOperand(0);
     Type *Ty = II.getType();
 
@@ -460,8 +463,16 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
       return IC.replaceInstUsesWith(II, ConstantFP::getNaN(Ty));
 
     if (ConstantFP *C = dyn_cast<ConstantFP>(Src)) {
-      if (C->isInfinity() && !C->isNegative())
-        return IC.replaceInstUsesWith(II, C);
+      if (C->isInfinity()) {
+        // exp2(+inf) -> +inf
+        // log2(+inf) -> +inf
+        if (!C->isNegative())
+          return IC.replaceInstUsesWith(II, C);
+
+        // exp2(-inf) -> 0
+        if (IsExp && C->isNegative())
+          return IC.replaceInstUsesWith(II, ConstantFP::getZero(Ty));
+      }
 
       if (II.isStrictFP())
         break;
@@ -472,10 +483,13 @@ GCNTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
       }
 
       // f32 instruction doesn't handle denormals, f16 does.
-      if (C->isZero() || (C->getValue().isDenormal() && Ty->isFloatTy()))
-        return IC.replaceInstUsesWith(II, ConstantFP::getInfinity(Ty, true));
+      if (C->isZero() || (C->getValue().isDenormal() && Ty->isFloatTy())) {
+        Constant *FoldedValue = IsLog ? ConstantFP::getInfinity(Ty, true)
+                                      : ConstantFP::get(Ty, 1.0);
+        return IC.replaceInstUsesWith(II, FoldedValue);
+      }
 
-      if (C->isNegative())
+      if (IsLog && C->isNegative())
         return IC.replaceInstUsesWith(II, ConstantFP::getNaN(Ty));
 
       // TODO: Full constant folding matching hardware behavior.

diff  --git a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
index bb5ef7ea7c28f..a661961537d69 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-intrinsics.ll
@@ -5922,8 +5922,7 @@ declare half @llvm.amdgcn.exp2.f16(half) nounwind readnone
 
 define float @test_constant_fold_exp2_f32_undef() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_undef(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float undef)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float undef)
   ret float %val
@@ -5931,8 +5930,7 @@ define float @test_constant_fold_exp2_f32_undef() {
 
 define float @test_constant_fold_exp2_f32_poison() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_poison(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float poison)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float poison
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float poison)
   ret float %val
@@ -5940,8 +5938,7 @@ define float @test_constant_fold_exp2_f32_poison() {
 
 define float @test_constant_fold_exp2_f32_p0() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_p0(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0.000000e+00)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 1.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0.0)
   ret float %val
@@ -5949,8 +5946,7 @@ define float @test_constant_fold_exp2_f32_p0() {
 
 define float @test_constant_fold_exp2_f32_n0() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_n0(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float -0.000000e+00)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 1.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float -0.0)
   ret float %val
@@ -6012,8 +6008,7 @@ define float @test_constant_fold_exp2_f32_n4() {
 
 define float @test_constant_fold_exp2_f32_subnormal() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_subnormal(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0x380FFFFFC0000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 1.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0x380FFFFFC0000000)
   ret float %val
@@ -6021,8 +6016,7 @@ define float @test_constant_fold_exp2_f32_subnormal() {
 
 define float @test_constant_fold_exp2_f32_negsubnormal() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_negsubnormal(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0xB80FFFFFC0000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 1.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0xB80FFFFFC0000000)
   ret float %val
@@ -6030,8 +6024,7 @@ define float @test_constant_fold_exp2_f32_negsubnormal() {
 
 define float @test_constant_fold_exp2_f32_pinf() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_pinf(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000000000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0x7FF0000000000000
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000000000000)
   ret float %val
@@ -6039,8 +6032,7 @@ define float @test_constant_fold_exp2_f32_pinf() {
 
 define float @test_constant_fold_exp2_f32_ninf() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_ninf(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0xFFF0000000000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0xFFF0000000000000)
   ret float %val
@@ -6066,8 +6058,7 @@ define float @test_constant_fold_exp2_f32_neg10() {
 
 define float @test_constant_fold_exp2_f32_qnan() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_qnan(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0x7FF8000000000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0x7FF8000000000000)
   ret float %val
@@ -6075,8 +6066,7 @@ define float @test_constant_fold_exp2_f32_qnan() {
 
 define float @test_constant_fold_exp2_f32_snan() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_snan(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000020000000)
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0x7FF8000020000000
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000020000000)
   ret float %val
@@ -6084,8 +6074,7 @@ define float @test_constant_fold_exp2_f32_snan() {
 
 define half @test_constant_fold_exp2_f16_p0() {
 ; CHECK-LABEL: @test_constant_fold_exp2_f16_p0(
-; CHECK-NEXT:    [[VAL:%.*]] = call half @llvm.amdgcn.exp2.f16(half 0xH0000)
-; CHECK-NEXT:    ret half [[VAL]]
+; CHECK-NEXT:    ret half 0xH3C00
 ;
   %val = call half @llvm.amdgcn.exp2.f16(half 0.0)
   ret half %val
@@ -6174,8 +6163,7 @@ define float @test_constant_fold_exp2_f32_neg_strictfp() strictfp {
 
 define float @test_constant_fold_exp2_f32_pinf_strictfp() strictfp {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_pinf_strictfp(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000000000000) #[[ATTR16]]
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0x7FF0000000000000
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0x7FF0000000000000) strictfp
   ret float %val
@@ -6183,8 +6171,7 @@ define float @test_constant_fold_exp2_f32_pinf_strictfp() strictfp {
 
 define float @test_constant_fold_exp2_f32_ninf_strictfp() strictfp {
 ; CHECK-LABEL: @test_constant_fold_exp2_f32_ninf_strictfp(
-; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.amdgcn.exp2.f32(float 0xFFF0000000000000) #[[ATTR16]]
-; CHECK-NEXT:    ret float [[VAL]]
+; CHECK-NEXT:    ret float 0.000000e+00
 ;
   %val = call float @llvm.amdgcn.exp2.f32(float 0xFFF0000000000000) strictfp
   ret float %val


        


More information about the llvm-commits mailing list