[PATCH] D43970: [InstCombine] Allow fptrunc (fpext X)) to be reduced to a single fpext if the trunc result type is larger than the original size

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 1 13:57:28 PST 2018


craig.topper created this revision.
craig.topper added reviewers: spatel, scanon, andrew.w.kaylor, efriedma.

If we are only removing bits that were added by the extend we should be able to use a smaller extend. I think.

We already reduce cases like this when there is binop in between. For example:

  define float @bar(half %a, half %x) {
      %b = fpext half %a to double
      %z = fpext half %x to double
      %y = fmul double %b, %z
      %c = fptrunc double %y to float
      ret float %c
  }


https://reviews.llvm.org/D43970

Files:
  lib/IR/Instructions.cpp
  test/Transforms/InstCombine/double-float-shrink-2.ll


Index: test/Transforms/InstCombine/double-float-shrink-2.ll
===================================================================
--- test/Transforms/InstCombine/double-float-shrink-2.ll
+++ test/Transforms/InstCombine/double-float-shrink-2.ll
@@ -448,8 +448,7 @@
 define float @test_shrink_intrin_floor_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_floor_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.floor.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -461,8 +460,7 @@
 define float @test_shrink_intrin_ceil_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_ceil_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.ceil.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -474,8 +472,7 @@
 define float @test_shrink_intrin_round_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_round_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.round.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -487,8 +484,7 @@
 define float @test_shrink_intrin_nearbyint_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_nearbyint_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.nearbyint.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -500,8 +496,7 @@
 define float @test_shrink_intrin_trunc_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_trunc_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.trunc.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -513,8 +508,7 @@
 define float @test_shrink_intrin_fabs_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_fabs_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call half @llvm.fabs.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
@@ -527,8 +521,7 @@
 define float @test_shrink_intrin_fabs_fast_fp16_src(half %C) {
 ; ALL-LABEL: @test_shrink_intrin_fabs_fast_fp16_src(
 ; ALL-NEXT:    [[E:%.*]] = call fast half @llvm.fabs.f16(half [[C:%.*]])
-; ALL-NEXT:    [[TMP1:%.*]] = fpext half [[E]] to double
-; ALL-NEXT:    [[F:%.*]] = fptrunc double [[TMP1]] to float
+; ALL-NEXT:    [[F:%.*]] = fpext half [[E]] to float
 ; ALL-NEXT:    ret float [[F]]
 ;
   %D = fpext half %C to double
Index: lib/IR/Instructions.cpp
===================================================================
--- lib/IR/Instructions.cpp
+++ lib/IR/Instructions.cpp
@@ -2267,12 +2267,19 @@
     case 9:
       // zext, sext -> zext, because sext can't sign extend after zext
       return Instruction::ZExt;
-    case 10:
+    case 10: {
       // fpext followed by ftrunc is allowed if the bit size returned to is
       // the same as the original, in which case its just a bitcast
       if (SrcTy == DstTy)
         return Instruction::BitCast;
+      // If we aren't discarding any bits that weren't extend, we can use
+      // a smaller fpext.
+      unsigned SrcSize = SrcTy->getScalarSizeInBits();
+      unsigned DstSize = DstTy->getScalarSizeInBits();
+      if (SrcSize < DstSize)
+        return Instruction::FPExt;
       return 0; // If the types are not the same we can't eliminate it.
+    }
     case 11: {
       // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
       if (!MidIntPtrTy)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43970.136599.patch
Type: text/x-patch
Size: 4360 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180301/178bcfc6/attachment.bin>


More information about the llvm-commits mailing list