Skip to content

[AMDGPU][GlobalISel] Minor G_BITCAST improvements and a fix to the artifact combiner - #215703

Open
andrzej-densityai wants to merge 1 commit into
llvm:mainfrom
andrzej-densityai:more_bitcasts
Open

[AMDGPU][GlobalISel] Minor G_BITCAST improvements and a fix to the artifact combiner#215703
andrzej-densityai wants to merge 1 commit into
llvm:mainfrom
andrzej-densityai:more_bitcasts

Conversation

@andrzej-densityai

Copy link
Copy Markdown
Contributor

This PR does two things in GlobalISel with extended LLT:

  • Minimally improves code quality by enrolling G_BITCAST into CSE and making constant traversal G_BITCAST-aware
  • Fixes a bug in the artifact combiner that produced invalid MIR when combining G_ANYEXT(G_TRUNC x)

This is not AMDGPU-specific, but it triggered test regenration in AMDGPU.

All AMDGPU results are minor improvements with the exception of ucmp.ll. ucmp.ll got worse for semi-related reasons. With my changes the MIR is the same up to amdgpu-regbank-combiner.

amdgpu-regbank-combiner now gives a different results:

Before:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(<2 x i16>) = COPY $sgpr0
  %1:sgpr(<2 x i16>) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(<2 x i16>)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(<2 x i16>)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %48:sgpr(i32) = G_BITCAST %0:sgpr(<2 x i16>)
  %49:sgpr(i32) = G_LSHR %48:sgpr, %38:sgpr(i32)
  %25:sgpr(i16) = G_TRUNC %48:sgpr(i32)
  %50:sgpr(i32) = G_BITCAST %1:sgpr(<2 x i16>)
  %51:sgpr(i32) = G_LSHR %50:sgpr, %38:sgpr(i32)
  %27:sgpr(i16) = G_TRUNC %50:sgpr(i32)
  %53:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %54:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %52:sgpr(i32) = G_ICMP intpred(ult), %53:sgpr(i32), %54:sgpr
  %55:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %51:sgpr
  %59:sgpr(i32) = G_CONSTANT i32 1
  %61:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %59:sgpr, %61:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %59:sgpr, %61:sgpr
  %21:sgpr(i32) = G_SELECT %52:sgpr(i32), %59:sgpr, %61:sgpr
  %22:sgpr(i32) = G_SELECT %55:sgpr(i32), %59:sgpr, %61:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

After:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(<2 x i16>) = COPY $sgpr0
  %1:sgpr(<2 x i16>) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(<2 x i16>)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %32:sgpr(i16) = G_TRUNC %39:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(<2 x i16>)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %34:sgpr(i16) = G_TRUNC %41:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %25:sgpr(i16) = COPY %31:sgpr(i16)
  %26:sgpr(i16) = COPY %32:sgpr(i16)
  %27:sgpr(i16) = COPY %33:sgpr(i16)
  %28:sgpr(i16) = COPY %34:sgpr(i16)
  %49:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %50:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %48:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %50:sgpr
  %52:sgpr(i32) = G_ZEXT %26:sgpr(i16)
  %53:sgpr(i32) = G_ZEXT %28:sgpr(i16)
  %51:sgpr(i32) = G_ICMP intpred(ult), %52:sgpr(i32), %53:sgpr
  %55:sgpr(i32) = G_CONSTANT i32 1
  %57:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %55:sgpr, %57:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %55:sgpr, %57:sgpr
  %21:sgpr(i32) = G_SELECT %48:sgpr(i32), %55:sgpr, %57:sgpr
  %22:sgpr(i32) = G_SELECT %51:sgpr(i32), %55:sgpr, %57:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

Due to the changes in this PR there's suddenly all those unnecessary virtual reg to virtual reg COPY. They come directly from this block of code:

auto [Dst0I32, Dst1I32] = unpackAExt(MI.getOperand(2).getReg());
.

FWIW I've made an experiment: replaced those two lines with:

auto OldReg0 = MI.getOperand(0).getReg();
      MRI.replaceRegWith(
          OldReg0, B.buildTrunc(MRI.getVRegAttrs(OldReg0), Dst0I32).getReg(0));
      auto OldReg1 = MI.getOperand(1).getReg();
      MRI.replaceRegWith(
          OldReg1, B.buildTrunc(MRI.getVRegAttrs(OldReg1), Dst1I32).getReg(0));

and got much better results, but I'm not sure what is the actual solution (auditing the file and avoiding B.buildXXX(...) like in the block above? running a cleanup pass?) and I think it's be outside of the scope of the changes here

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-amdgpu

Author: andrzej-densityai

Changes

This PR does two things in GlobalISel with extended LLT:

  • Minimally improves code quality by enrolling G_BITCAST into CSE and making constant traversal G_BITCAST-aware
  • Fixes a bug in the artifact combiner that produced invalid MIR when combining G_ANYEXT(G_TRUNC x)

This is not AMDGPU-specific, but it triggered test regenration in AMDGPU.

All AMDGPU results are minor improvements with the exception of ucmp.ll. ucmp.ll got worse for semi-related reasons. With my changes the MIR is the same up to amdgpu-regbank-combiner.

amdgpu-regbank-combiner now gives a different results:

Before:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(&lt;2 x i16&gt;) = COPY $sgpr0
  %1:sgpr(&lt;2 x i16&gt;) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %48:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %49:sgpr(i32) = G_LSHR %48:sgpr, %38:sgpr(i32)
  %25:sgpr(i16) = G_TRUNC %48:sgpr(i32)
  %50:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %51:sgpr(i32) = G_LSHR %50:sgpr, %38:sgpr(i32)
  %27:sgpr(i16) = G_TRUNC %50:sgpr(i32)
  %53:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %54:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %52:sgpr(i32) = G_ICMP intpred(ult), %53:sgpr(i32), %54:sgpr
  %55:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %51:sgpr
  %59:sgpr(i32) = G_CONSTANT i32 1
  %61:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %59:sgpr, %61:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %59:sgpr, %61:sgpr
  %21:sgpr(i32) = G_SELECT %52:sgpr(i32), %59:sgpr, %61:sgpr
  %22:sgpr(i32) = G_SELECT %55:sgpr(i32), %59:sgpr, %61:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

After:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(&lt;2 x i16&gt;) = COPY $sgpr0
  %1:sgpr(&lt;2 x i16&gt;) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %32:sgpr(i16) = G_TRUNC %39:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %34:sgpr(i16) = G_TRUNC %41:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %25:sgpr(i16) = COPY %31:sgpr(i16)
  %26:sgpr(i16) = COPY %32:sgpr(i16)
  %27:sgpr(i16) = COPY %33:sgpr(i16)
  %28:sgpr(i16) = COPY %34:sgpr(i16)
  %49:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %50:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %48:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %50:sgpr
  %52:sgpr(i32) = G_ZEXT %26:sgpr(i16)
  %53:sgpr(i32) = G_ZEXT %28:sgpr(i16)
  %51:sgpr(i32) = G_ICMP intpred(ult), %52:sgpr(i32), %53:sgpr
  %55:sgpr(i32) = G_CONSTANT i32 1
  %57:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %55:sgpr, %57:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %55:sgpr, %57:sgpr
  %21:sgpr(i32) = G_SELECT %48:sgpr(i32), %55:sgpr, %57:sgpr
  %22:sgpr(i32) = G_SELECT %51:sgpr(i32), %55:sgpr, %57:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

Due to the changes in this PR there's suddenly all those unnecessary virtual reg to virtual reg COPY. They come directly from this block of code:

auto [Dst0I32, Dst1I32] = unpackAExt(MI.getOperand(2).getReg());
.

FWIW I've made an experiment: replaced those two lines with:

auto OldReg0 = MI.getOperand(0).getReg();
      MRI.replaceRegWith(
          OldReg0, B.buildTrunc(MRI.getVRegAttrs(OldReg0), Dst0I32).getReg(0));
      auto OldReg1 = MI.getOperand(1).getReg();
      MRI.replaceRegWith(
          OldReg1, B.buildTrunc(MRI.getVRegAttrs(OldReg1), Dst1I32).getReg(0));

and got much better results, but I'm not sure what is the actual solution (auditing the file and avoiding B.buildXXX(...) like in the block above? running a cleanup pass?) and I think it's be outside of the scope of the changes here


Patch is 282.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215703.diff

16 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h (+5-1)
  • (modified) llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp (+1)
  • (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+1)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir (+17)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll (+11-15)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir (+11-15)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir (+17-20)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll (+318-432)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.load.2d.ll (+16-16)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-phi.mir (+11-17)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.s16.mir (+24-40)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.intersect_ray.ll (+62-129)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/select-to-fmin-fmax.ll (+30-32)
  • (modified) llvm/test/CodeGen/AMDGPU/integer-mad-patterns.ll (+32-32)
  • (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll (+373-603)
  • (modified) llvm/test/CodeGen/AMDGPU/ucmp.ll (+5-2)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 08e567f2e640a..6bad4ebcff181 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -71,9 +71,13 @@ class LegalizationArtifactCombiner {
     Register TruncSrc;
     if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
       LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
-      if (MRI.getType(DstReg) == MRI.getType(TruncSrc))
+      auto DstType = MRI.getType(DstReg);
+      auto SrcType = MRI.getType(TruncSrc);
+      if (DstType == SrcType)
         replaceRegOrBuildCopy(DstReg, TruncSrc, MRI, Builder, UpdatedDefs,
                               Observer);
+      else if (DstType.getSizeInBits() == SrcType.getSizeInBits())
+        Builder.buildBitcast(DstReg, TruncSrc);
       else
         Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
       UpdatedDefs.push_back(DstReg);
diff --git a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
index 2967fc3a602d1..e429db90bb95e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
@@ -71,6 +71,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
   case TargetOpcode::G_FMINNUM:
   case TargetOpcode::G_FMAXNUM_IEEE:
   case TargetOpcode::G_FMINNUM_IEEE:
+  case TargetOpcode::G_BITCAST:
     return true;
   }
   return false;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index c555b67d9198c..c8639ee890539 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -363,6 +363,7 @@ getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
         return std::nullopt;
       break;
     case TargetOpcode::G_INTTOPTR:
+    case TargetOpcode::G_BITCAST:
       VReg = MI->getOperand(1).getReg();
       break;
     default:
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
index 9cc747f1f5361..e972e7a2895e5 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
@@ -73,3 +73,20 @@ body: |
     %2:_(<3 x s32>) = G_ANYEXT %1
     $vgpr0_vgpr1_vgpr2 = COPY %2
 ...
+
+---
+name: test_anyext_trunc_i32_to_i16_to_f32
+body: |
+  bb.0:
+    liveins: $vgpr0
+    ; CHECK-LABEL: name: test_anyext_trunc_i32_to_i16_to_f32
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $vgpr0
+    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(f32) = G_BITCAST [[COPY]](i32)
+    ; CHECK-NEXT: $vgpr0 = COPY [[BITCAST]](f32)
+    %0:_(i32) = COPY $vgpr0
+    %1:_(i16) = G_TRUNC %0(i32)
+    %2:_(f32) = G_ANYEXT %1(i16)
+    $vgpr0 = COPY %2(f32)
+...
\ No newline at end of file
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
index aa389eec4f991..bb9984797d2ae 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
@@ -29,18 +29,16 @@ define <2 x i16> @vop3p_add_v2i16(<2 x i16> %arg0) #0 {
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
   ; CHECK-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; CHECK-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](<2 x i16>)
-  ; CHECK-NEXT:   [[TRUNC2:%[0-9]+]]:_(i16) = G_TRUNC [[BITCAST1]](i32)
-  ; CHECK-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
-  ; CHECK-NEXT:   [[TRUNC3:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
-  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i16) = G_ADD [[TRUNC]], [[TRUNC2]]
-  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i16) = G_ADD [[TRUNC1]], [[TRUNC3]]
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(i16) = COPY [[TRUNC]](i16)
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(i16) = COPY [[TRUNC1]](i16)
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i16) = G_ADD [[TRUNC]], [[COPY1]]
+  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i16) = G_ADD [[TRUNC1]], [[COPY2]]
   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[ADD]](i16)
   ; CHECK-NEXT:   [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[ADD1]](i16)
   ; CHECK-NEXT:   [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
   ; CHECK-NEXT:   [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
-  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
-  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST2]](<2 x i16>)
+  ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST1]](<2 x i16>)
   ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
   %add = add <2 x i16> %arg0, %arg0
   ret <2 x i16> %add
@@ -69,18 +67,16 @@ define <2 x i16> @halfinsts_add_v2i16(<2 x i16> %arg0) #1 {
   ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST]](<2 x i16>)
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
   ; CHECK-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
-  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST]](<2 x i16>)
-  ; CHECK-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
-  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i32) = G_ADD [[BITCAST1]], [[BITCAST2]]
-  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i32) = G_ADD [[LSHR]], [[LSHR1]]
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i32) = G_ADD [[BITCAST1]], [[BITCAST1]]
+  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i32) = G_ADD [[LSHR]], [[LSHR]]
   ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 65535
   ; CHECK-NEXT:   [[AND:%[0-9]+]]:_(i32) = G_AND [[ADD]], [[C1]]
   ; CHECK-NEXT:   [[AND1:%[0-9]+]]:_(i32) = G_AND [[ADD1]], [[C1]]
   ; CHECK-NEXT:   [[SHL:%[0-9]+]]:_(i32) = G_SHL [[AND1]], [[C]](i32)
   ; CHECK-NEXT:   [[OR:%[0-9]+]]:_(i32) = G_OR [[AND]], [[SHL]]
-  ; CHECK-NEXT:   [[BITCAST3:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
-  ; CHECK-NEXT:   [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST3]](<2 x i16>)
-  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST4]](i32)
+  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
+  ; CHECK-NEXT:   [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST2]](<2 x i16>)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST3]](i32)
   ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
   %add = add <2 x i16> %arg0, %arg0
   ret <2 x i16> %add
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
index 6efd646679157..d8def4b8b4c5e 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
@@ -831,29 +831,25 @@ body: |
     ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST2]](i32)
     ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
     ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR1]](i32)
-    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](<2 x s16>)
-    ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST3]](i32)
-    ; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST3]], [[C]](i32)
-    ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR2]](i32)
-    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](<2 x s16>)
-    ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST4]](i32)
-    ; CHECK-NEXT: [[LSHR3:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST4]], [[C]](i32)
-    ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR3]](i32)
-    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC4]]
-    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s16) = G_ADD [[TRUNC1]], [[TRUNC5]]
-    ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s16) = G_ADD [[TRUNC2]], [[TRUNC6]]
-    ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s16) = G_ADD [[TRUNC3]], [[TRUNC7]]
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY [[TRUNC]](s16)
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s16) = COPY [[TRUNC1]](s16)
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s16) = COPY [[TRUNC2]](s16)
+    ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s16) = COPY [[TRUNC3]](s16)
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[COPY1]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s16) = G_ADD [[TRUNC1]], [[COPY2]]
+    ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s16) = G_ADD [[TRUNC2]], [[COPY3]]
+    ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s16) = G_ADD [[TRUNC3]], [[COPY4]]
     ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[ADD]](s16)
     ; CHECK-NEXT: [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[ADD1]](s16)
     ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
     ; CHECK-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
-    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR]](i32)
+    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR]](i32)
     ; CHECK-NEXT: [[ZEXT2:%[0-9]+]]:_(i32) = G_ZEXT [[ADD2]](s16)
     ; CHECK-NEXT: [[ZEXT3:%[0-9]+]]:_(i32) = G_ZEXT [[ADD3]](s16)
     ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(i32) = G_SHL [[ZEXT3]], [[C]](i32)
     ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(i32) = G_OR [[ZEXT2]], [[SHL1]]
-    ; CHECK-NEXT: [[BITCAST6:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR1]](i32)
-    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[BITCAST5]](<2 x s16>), [[BITCAST6]](<2 x s16>)
+    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR1]](i32)
+    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[BITCAST3]](<2 x s16>), [[BITCAST4]](<2 x s16>)
     ; CHECK-NEXT: S_ENDPGM 0, implicit [[CONCAT_VECTORS]](<4 x s16>)
     %0:_(<2 x s32>) = COPY $vgpr0_vgpr1
     %1:_(<4 x s16>) = G_BITCAST %0
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
index 3272a08aadb75..fbdce424435c3 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
@@ -204,14 +204,13 @@ body: |
     ; GFX6-NEXT: [[C10:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
     ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f64) = G_SELECT [[FCMP]](i1), [[C9]], [[C10]]
     ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT2]](f64)
-    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i64) = G_BITCAST [[COPY]](f64)
     ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i64) = G_CONSTANT i64 -9223372036854775808
     ; GFX6-NEXT: [[C12:%[0-9]+]]:_(i64) = G_CONSTANT i64 9223372036854775807
     ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i64) = G_AND [[BITCAST2]], [[C12]]
-    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST3]], [[C11]]
+    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST]], [[C11]]
     ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i64) = disjoint G_OR [[AND2]], [[AND3]]
-    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
-    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST4]]
+    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
+    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST3]]
     ; GFX6-NEXT: $vgpr0_vgpr1 = COPY [[FADD1]](f64)
     ;
     ; GFX8-LABEL: name: test_intrinsic_round_f64
@@ -429,40 +428,38 @@ body: |
     ; GFX6-NEXT: [[C10:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
     ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f64) = G_SELECT [[FCMP]](i1), [[C9]], [[C10]]
     ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT2]](f64)
-    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i64) = G_BITCAST [[UV]](f64)
     ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i64) = G_CONSTANT i64 -9223372036854775808
     ; GFX6-NEXT: [[C12:%[0-9]+]]:_(i64) = G_CONSTANT i64 9223372036854775807
     ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i64) = G_AND [[BITCAST2]], [[C12]]
-    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST3]], [[C11]]
+    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST]], [[C11]]
     ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i64) = disjoint G_OR [[AND2]], [[AND3]]
-    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
-    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST4]]
-    ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
-    ; GFX6-NEXT: [[UV4:%[0-9]+]]:_(i32), [[UV5:%[0-9]+]]:_(i32) = G_UNMERGE_VALUES [[BITCAST5]](i64)
+    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
+    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST3]]
+    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
+    ; GFX6-NEXT: [[UV4:%[0-9]+]]:_(i32), [[UV5:%[0-9]+]]:_(i32) = G_UNMERGE_VALUES [[BITCAST4]](i64)
     ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(i32) = G_INTRINSIC intrinsic(@llvm.amdgcn.ubfe), [[UV5]](i32), [[C]](i32), [[C1]](i32)
     ; GFX6-NEXT: [[SUB1:%[0-9]+]]:_(i32) = G_SUB [[INT1]], [[C2]]
     ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(i32) = G_AND [[UV5]], [[C3]]
     ; GFX6-NEXT: [[MV1:%[0-9]+]]:_(i64) = G_MERGE_VALUES [[C5]](i32), [[AND4]](i32)
     ; GFX6-NEXT: [[ASHR1:%[0-9]+]]:_(i64) = G_ASHR [[C4]], [[SUB1]](i32)
     ; GFX6-NEXT: [[XOR1:%[0-9]+]]:_(i64) = G_XOR [[ASHR1]], [[C6]]
-    ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i64) = G_AND [[BITCAST5]], [[XOR1]]
+    ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i64) = G_AND [[BITCAST4]], [[XOR1]]
     ; GFX6-NEXT: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[SUB1]](i32), [[C5]]
     ; GFX6-NEXT: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), [[SUB1]](i32), [[C7]]
     ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(i64) = G_SELECT [[ICMP2]](s1), [[MV1]], [[AND5]]
-    ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(i64) = G_SELECT [[ICMP3]](s1), [[BITCAST5]], [[SELECT3]]
-    ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(f64) = G_BITCAST [[SELECT4]](i64)
-    ; GFX6-NEXT: [[FNEG1:%[0-9]+]]:_(f64) = G_FNEG [[BITCAST6]]
+    ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(i64) = G_SELECT [[ICMP3]](s1), [[BITCAST4]], [[SELECT3]]
+    ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(f64) = G_BITCAST [[SELECT4]](i64)
+    ; GFX6-NEXT: [[FNEG1:%[0-9]+]]:_(f64) = G_FNEG [[BITCAST5]]
     ; GFX6-NEXT: [[FADD2:%[0-9]+]]:_(f64) = G_FADD [[UV1]], [[FNEG1]]
     ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f64) = G_FABS [[FADD2]]
     ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(i1) = G_FCMP floatpred(oge), [[FABS1]](f64), [[C8]]
     ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f64) = G_SELECT [[FCMP1]](i1), [[C9]], [[C10]]
-    ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT5]](f64)
-    ; GFX6-NEXT: [[BITCAST8:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
-    ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i64) = G_AND [[BITCAST7]], [[C12]]
-    ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(i64) = G_AND [[BITCAST8]], [[C11]]
+    ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT5]](f64)
+    ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i64) = G_AND [[BITCAST6]], [[C12]]
+    ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(i64) = G_AND [[BITCAST4]], [[C11]]
     ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i64) = disjoint G_OR [[AND6]], [[AND7]]
-    ; GFX6-NEXT: [[BITCAST9:%[0-9]+]]:_(f64) = G_BITCAST [[OR1]](i64)
-    ; GFX6-NEXT: [[FADD3:%[0-9]+]]:_(f64) = G_FADD [[BITCAST6]], [[BITCAST9]]
+    ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(f64) = G_BITCAST [[OR1]](i64)
+    ; GFX6-NEXT: [[FADD3:%[0-9]+]]:_(f64) = G_FADD [[BITCAST5]], [[BITCAST7]]
     ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f64>) = G_BUILD_VECTOR [[FADD1]](f64), [[FADD3]](f64)
     ; GFX6-NEXT: $vgpr0_vgpr1_vgpr2_vgpr3 = COPY [[BUILD_VECTOR]](<2 x f64>)
     ;
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
index d761f2cd8a97e..58559584c4959 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
@@ -113,9 +113,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX9-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX9-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX9-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX9-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 3 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -144,9 +143,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX10NSA-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX10NSA-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX10NSA-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX10NSA-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX10NSA-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX10NSA-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX10NSA-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX10NSA-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX10NSA-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX10NSA-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 1 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -175,9 +173,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX12-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX12-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX12-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX12-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX12-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX12-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX12-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX12-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX12-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX12-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 1 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -214,12 +211,11 @@ define amdgpu_ps <4 x float> @load_3d(<8 x i32> inreg %rsrc, <2 x i16> %coords_l
   ; GFX9-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX9-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
-  ; GFX9-NEXT:   [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[COPY9]](<2 x i16>)
-  ; GFX9-NEXT:   [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
+  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY9]](<2 x i16>)
+  ; GFX9-NEXT:   [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC2:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR2]](i32)
   ; GFX9-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX9-NEXT:   [[DEF:%[0-9]+]]:_(i16) = G_IMPLICIT_DEF
@@ -252,12 +248,11 @@ define amdgpu_ps <4 x float> @load_3d(<8 x i32> inreg %rsrc, <2 x i16> %coords_l
   ; GFX10NSA-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COP...
[truncated]

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-globalisel

Author: andrzej-densityai

Changes

This PR does two things in GlobalISel with extended LLT:

  • Minimally improves code quality by enrolling G_BITCAST into CSE and making constant traversal G_BITCAST-aware
  • Fixes a bug in the artifact combiner that produced invalid MIR when combining G_ANYEXT(G_TRUNC x)

This is not AMDGPU-specific, but it triggered test regenration in AMDGPU.

All AMDGPU results are minor improvements with the exception of ucmp.ll. ucmp.ll got worse for semi-related reasons. With my changes the MIR is the same up to amdgpu-regbank-combiner.

amdgpu-regbank-combiner now gives a different results:

Before:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(&lt;2 x i16&gt;) = COPY $sgpr0
  %1:sgpr(&lt;2 x i16&gt;) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %48:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %49:sgpr(i32) = G_LSHR %48:sgpr, %38:sgpr(i32)
  %25:sgpr(i16) = G_TRUNC %48:sgpr(i32)
  %50:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %51:sgpr(i32) = G_LSHR %50:sgpr, %38:sgpr(i32)
  %27:sgpr(i16) = G_TRUNC %50:sgpr(i32)
  %53:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %54:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %52:sgpr(i32) = G_ICMP intpred(ult), %53:sgpr(i32), %54:sgpr
  %55:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %51:sgpr
  %59:sgpr(i32) = G_CONSTANT i32 1
  %61:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %59:sgpr, %61:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %59:sgpr, %61:sgpr
  %21:sgpr(i32) = G_SELECT %52:sgpr(i32), %59:sgpr, %61:sgpr
  %22:sgpr(i32) = G_SELECT %55:sgpr(i32), %59:sgpr, %61:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

After:

bb.1 (%ir-block.0):
  liveins: $sgpr0, $sgpr1
  %0:sgpr(&lt;2 x i16&gt;) = COPY $sgpr0
  %1:sgpr(&lt;2 x i16&gt;) = COPY $sgpr1
  %37:sgpr(i32) = G_BITCAST %0:sgpr(&lt;2 x i16&gt;)
  %38:sgpr(i32) = G_CONSTANT i32 16
  %39:sgpr(i32) = G_LSHR %37:sgpr, %38:sgpr(i32)
  %31:sgpr(i16) = G_TRUNC %37:sgpr(i32)
  %32:sgpr(i16) = G_TRUNC %39:sgpr(i32)
  %40:sgpr(i32) = G_BITCAST %1:sgpr(&lt;2 x i16&gt;)
  %41:sgpr(i32) = G_LSHR %40:sgpr, %38:sgpr(i32)
  %33:sgpr(i16) = G_TRUNC %40:sgpr(i32)
  %34:sgpr(i16) = G_TRUNC %41:sgpr(i32)
  %43:sgpr(i32) = G_ZEXT %31:sgpr(i16)
  %44:sgpr(i32) = G_ZEXT %33:sgpr(i16)
  %42:sgpr(i32) = G_ICMP intpred(ugt), %43:sgpr(i32), %44:sgpr
  %45:sgpr(i32) = G_ICMP intpred(ugt), %39:sgpr(i32), %41:sgpr
  %25:sgpr(i16) = COPY %31:sgpr(i16)
  %26:sgpr(i16) = COPY %32:sgpr(i16)
  %27:sgpr(i16) = COPY %33:sgpr(i16)
  %28:sgpr(i16) = COPY %34:sgpr(i16)
  %49:sgpr(i32) = G_ZEXT %25:sgpr(i16)
  %50:sgpr(i32) = G_ZEXT %27:sgpr(i16)
  %48:sgpr(i32) = G_ICMP intpred(ult), %49:sgpr(i32), %50:sgpr
  %52:sgpr(i32) = G_ZEXT %26:sgpr(i16)
  %53:sgpr(i32) = G_ZEXT %28:sgpr(i16)
  %51:sgpr(i32) = G_ICMP intpred(ult), %52:sgpr(i32), %53:sgpr
  %55:sgpr(i32) = G_CONSTANT i32 1
  %57:sgpr(i32) = G_CONSTANT i32 0
  %19:sgpr(i32) = G_SELECT %42:sgpr(i32), %55:sgpr, %57:sgpr
  %20:sgpr(i32) = G_SELECT %45:sgpr(i32), %55:sgpr, %57:sgpr
  %21:sgpr(i32) = G_SELECT %48:sgpr(i32), %55:sgpr, %57:sgpr
  %22:sgpr(i32) = G_SELECT %51:sgpr(i32), %55:sgpr, %57:sgpr
  %23:sgpr(i32) = G_SUB %19:sgpr, %21:sgpr
  %24:sgpr(i32) = G_SUB %20:sgpr, %22:sgpr
  $vgpr0 = COPY %23:sgpr(i32)
  $vgpr1 = COPY %24:sgpr(i32)
  SI_RETURN implicit $vgpr0, implicit $vgpr1

Due to the changes in this PR there's suddenly all those unnecessary virtual reg to virtual reg COPY. They come directly from this block of code:

auto [Dst0I32, Dst1I32] = unpackAExt(MI.getOperand(2).getReg());
.

FWIW I've made an experiment: replaced those two lines with:

auto OldReg0 = MI.getOperand(0).getReg();
      MRI.replaceRegWith(
          OldReg0, B.buildTrunc(MRI.getVRegAttrs(OldReg0), Dst0I32).getReg(0));
      auto OldReg1 = MI.getOperand(1).getReg();
      MRI.replaceRegWith(
          OldReg1, B.buildTrunc(MRI.getVRegAttrs(OldReg1), Dst1I32).getReg(0));

and got much better results, but I'm not sure what is the actual solution (auditing the file and avoiding B.buildXXX(...) like in the block above? running a cleanup pass?) and I think it's be outside of the scope of the changes here


Patch is 282.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215703.diff

16 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h (+5-1)
  • (modified) llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp (+1)
  • (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+1)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir (+17)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll (+11-15)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir (+11-15)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir (+17-20)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll (+318-432)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.load.2d.ll (+16-16)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-phi.mir (+11-17)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.s16.mir (+24-40)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.intersect_ray.ll (+62-129)
  • (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/select-to-fmin-fmax.ll (+30-32)
  • (modified) llvm/test/CodeGen/AMDGPU/integer-mad-patterns.ll (+32-32)
  • (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll (+373-603)
  • (modified) llvm/test/CodeGen/AMDGPU/ucmp.ll (+5-2)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 08e567f2e640a..6bad4ebcff181 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -71,9 +71,13 @@ class LegalizationArtifactCombiner {
     Register TruncSrc;
     if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
       LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
-      if (MRI.getType(DstReg) == MRI.getType(TruncSrc))
+      auto DstType = MRI.getType(DstReg);
+      auto SrcType = MRI.getType(TruncSrc);
+      if (DstType == SrcType)
         replaceRegOrBuildCopy(DstReg, TruncSrc, MRI, Builder, UpdatedDefs,
                               Observer);
+      else if (DstType.getSizeInBits() == SrcType.getSizeInBits())
+        Builder.buildBitcast(DstReg, TruncSrc);
       else
         Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
       UpdatedDefs.push_back(DstReg);
diff --git a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
index 2967fc3a602d1..e429db90bb95e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
@@ -71,6 +71,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
   case TargetOpcode::G_FMINNUM:
   case TargetOpcode::G_FMAXNUM_IEEE:
   case TargetOpcode::G_FMINNUM_IEEE:
+  case TargetOpcode::G_BITCAST:
     return true;
   }
   return false;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index c555b67d9198c..c8639ee890539 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -363,6 +363,7 @@ getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
         return std::nullopt;
       break;
     case TargetOpcode::G_INTTOPTR:
+    case TargetOpcode::G_BITCAST:
       VReg = MI->getOperand(1).getReg();
       break;
     default:
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
index 9cc747f1f5361..e972e7a2895e5 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/artifact-combiner-anyext.mir
@@ -73,3 +73,20 @@ body: |
     %2:_(<3 x s32>) = G_ANYEXT %1
     $vgpr0_vgpr1_vgpr2 = COPY %2
 ...
+
+---
+name: test_anyext_trunc_i32_to_i16_to_f32
+body: |
+  bb.0:
+    liveins: $vgpr0
+    ; CHECK-LABEL: name: test_anyext_trunc_i32_to_i16_to_f32
+    ; CHECK: liveins: $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $vgpr0
+    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(f32) = G_BITCAST [[COPY]](i32)
+    ; CHECK-NEXT: $vgpr0 = COPY [[BITCAST]](f32)
+    %0:_(i32) = COPY $vgpr0
+    %1:_(i16) = G_TRUNC %0(i32)
+    %2:_(f32) = G_ANYEXT %1(i16)
+    $vgpr0 = COPY %2(f32)
+...
\ No newline at end of file
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
index aa389eec4f991..bb9984797d2ae 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/dummy-target.ll
@@ -29,18 +29,16 @@ define <2 x i16> @vop3p_add_v2i16(<2 x i16> %arg0) #0 {
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
   ; CHECK-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; CHECK-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](<2 x i16>)
-  ; CHECK-NEXT:   [[TRUNC2:%[0-9]+]]:_(i16) = G_TRUNC [[BITCAST1]](i32)
-  ; CHECK-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
-  ; CHECK-NEXT:   [[TRUNC3:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
-  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i16) = G_ADD [[TRUNC]], [[TRUNC2]]
-  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i16) = G_ADD [[TRUNC1]], [[TRUNC3]]
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(i16) = COPY [[TRUNC]](i16)
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(i16) = COPY [[TRUNC1]](i16)
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i16) = G_ADD [[TRUNC]], [[COPY1]]
+  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i16) = G_ADD [[TRUNC1]], [[COPY2]]
   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[ADD]](i16)
   ; CHECK-NEXT:   [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[ADD1]](i16)
   ; CHECK-NEXT:   [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
   ; CHECK-NEXT:   [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
-  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
-  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST2]](<2 x i16>)
+  ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST1]](<2 x i16>)
   ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
   %add = add <2 x i16> %arg0, %arg0
   ret <2 x i16> %add
@@ -69,18 +67,16 @@ define <2 x i16> @halfinsts_add_v2i16(<2 x i16> %arg0) #1 {
   ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST]](<2 x i16>)
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
   ; CHECK-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
-  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST]](<2 x i16>)
-  ; CHECK-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
-  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i32) = G_ADD [[BITCAST1]], [[BITCAST2]]
-  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i32) = G_ADD [[LSHR]], [[LSHR1]]
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(i32) = G_ADD [[BITCAST1]], [[BITCAST1]]
+  ; CHECK-NEXT:   [[ADD1:%[0-9]+]]:_(i32) = G_ADD [[LSHR]], [[LSHR]]
   ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 65535
   ; CHECK-NEXT:   [[AND:%[0-9]+]]:_(i32) = G_AND [[ADD]], [[C1]]
   ; CHECK-NEXT:   [[AND1:%[0-9]+]]:_(i32) = G_AND [[ADD1]], [[C1]]
   ; CHECK-NEXT:   [[SHL:%[0-9]+]]:_(i32) = G_SHL [[AND1]], [[C]](i32)
   ; CHECK-NEXT:   [[OR:%[0-9]+]]:_(i32) = G_OR [[AND]], [[SHL]]
-  ; CHECK-NEXT:   [[BITCAST3:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
-  ; CHECK-NEXT:   [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST3]](<2 x i16>)
-  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST4]](i32)
+  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(<2 x i16>) = G_BITCAST [[OR]](i32)
+  ; CHECK-NEXT:   [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[BITCAST2]](<2 x i16>)
+  ; CHECK-NEXT:   $vgpr0 = COPY [[BITCAST3]](i32)
   ; CHECK-NEXT:   SI_RETURN implicit $vgpr0
   %add = add <2 x i16> %arg0, %arg0
   ret <2 x i16> %add
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
index 6efd646679157..d8def4b8b4c5e 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-bitcast.mir
@@ -831,29 +831,25 @@ body: |
     ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST2]](i32)
     ; CHECK-NEXT: [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
     ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR1]](i32)
-    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](<2 x s16>)
-    ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST3]](i32)
-    ; CHECK-NEXT: [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST3]], [[C]](i32)
-    ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR2]](i32)
-    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](<2 x s16>)
-    ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST4]](i32)
-    ; CHECK-NEXT: [[LSHR3:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST4]], [[C]](i32)
-    ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR3]](i32)
-    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC4]]
-    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s16) = G_ADD [[TRUNC1]], [[TRUNC5]]
-    ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s16) = G_ADD [[TRUNC2]], [[TRUNC6]]
-    ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s16) = G_ADD [[TRUNC3]], [[TRUNC7]]
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY [[TRUNC]](s16)
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s16) = COPY [[TRUNC1]](s16)
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s16) = COPY [[TRUNC2]](s16)
+    ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s16) = COPY [[TRUNC3]](s16)
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[COPY1]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s16) = G_ADD [[TRUNC1]], [[COPY2]]
+    ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s16) = G_ADD [[TRUNC2]], [[COPY3]]
+    ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s16) = G_ADD [[TRUNC3]], [[COPY4]]
     ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[ADD]](s16)
     ; CHECK-NEXT: [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[ADD1]](s16)
     ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
     ; CHECK-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
-    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR]](i32)
+    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR]](i32)
     ; CHECK-NEXT: [[ZEXT2:%[0-9]+]]:_(i32) = G_ZEXT [[ADD2]](s16)
     ; CHECK-NEXT: [[ZEXT3:%[0-9]+]]:_(i32) = G_ZEXT [[ADD3]](s16)
     ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(i32) = G_SHL [[ZEXT3]], [[C]](i32)
     ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(i32) = G_OR [[ZEXT2]], [[SHL1]]
-    ; CHECK-NEXT: [[BITCAST6:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR1]](i32)
-    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[BITCAST5]](<2 x s16>), [[BITCAST6]](<2 x s16>)
+    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[OR1]](i32)
+    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[BITCAST3]](<2 x s16>), [[BITCAST4]](<2 x s16>)
     ; CHECK-NEXT: S_ENDPGM 0, implicit [[CONCAT_VECTORS]](<4 x s16>)
     %0:_(<2 x s32>) = COPY $vgpr0_vgpr1
     %1:_(<4 x s16>) = G_BITCAST %0
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
index 3272a08aadb75..fbdce424435c3 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-intrinsic-round.mir
@@ -204,14 +204,13 @@ body: |
     ; GFX6-NEXT: [[C10:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
     ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f64) = G_SELECT [[FCMP]](i1), [[C9]], [[C10]]
     ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT2]](f64)
-    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i64) = G_BITCAST [[COPY]](f64)
     ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i64) = G_CONSTANT i64 -9223372036854775808
     ; GFX6-NEXT: [[C12:%[0-9]+]]:_(i64) = G_CONSTANT i64 9223372036854775807
     ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i64) = G_AND [[BITCAST2]], [[C12]]
-    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST3]], [[C11]]
+    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST]], [[C11]]
     ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i64) = disjoint G_OR [[AND2]], [[AND3]]
-    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
-    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST4]]
+    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
+    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST3]]
     ; GFX6-NEXT: $vgpr0_vgpr1 = COPY [[FADD1]](f64)
     ;
     ; GFX8-LABEL: name: test_intrinsic_round_f64
@@ -429,40 +428,38 @@ body: |
     ; GFX6-NEXT: [[C10:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
     ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f64) = G_SELECT [[FCMP]](i1), [[C9]], [[C10]]
     ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT2]](f64)
-    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i64) = G_BITCAST [[UV]](f64)
     ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i64) = G_CONSTANT i64 -9223372036854775808
     ; GFX6-NEXT: [[C12:%[0-9]+]]:_(i64) = G_CONSTANT i64 9223372036854775807
     ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i64) = G_AND [[BITCAST2]], [[C12]]
-    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST3]], [[C11]]
+    ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(i64) = G_AND [[BITCAST]], [[C11]]
     ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i64) = disjoint G_OR [[AND2]], [[AND3]]
-    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
-    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST4]]
-    ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
-    ; GFX6-NEXT: [[UV4:%[0-9]+]]:_(i32), [[UV5:%[0-9]+]]:_(i32) = G_UNMERGE_VALUES [[BITCAST5]](i64)
+    ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(f64) = G_BITCAST [[OR]](i64)
+    ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f64) = G_FADD [[BITCAST1]], [[BITCAST3]]
+    ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
+    ; GFX6-NEXT: [[UV4:%[0-9]+]]:_(i32), [[UV5:%[0-9]+]]:_(i32) = G_UNMERGE_VALUES [[BITCAST4]](i64)
     ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(i32) = G_INTRINSIC intrinsic(@llvm.amdgcn.ubfe), [[UV5]](i32), [[C]](i32), [[C1]](i32)
     ; GFX6-NEXT: [[SUB1:%[0-9]+]]:_(i32) = G_SUB [[INT1]], [[C2]]
     ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(i32) = G_AND [[UV5]], [[C3]]
     ; GFX6-NEXT: [[MV1:%[0-9]+]]:_(i64) = G_MERGE_VALUES [[C5]](i32), [[AND4]](i32)
     ; GFX6-NEXT: [[ASHR1:%[0-9]+]]:_(i64) = G_ASHR [[C4]], [[SUB1]](i32)
     ; GFX6-NEXT: [[XOR1:%[0-9]+]]:_(i64) = G_XOR [[ASHR1]], [[C6]]
-    ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i64) = G_AND [[BITCAST5]], [[XOR1]]
+    ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i64) = G_AND [[BITCAST4]], [[XOR1]]
     ; GFX6-NEXT: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[SUB1]](i32), [[C5]]
     ; GFX6-NEXT: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), [[SUB1]](i32), [[C7]]
     ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(i64) = G_SELECT [[ICMP2]](s1), [[MV1]], [[AND5]]
-    ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(i64) = G_SELECT [[ICMP3]](s1), [[BITCAST5]], [[SELECT3]]
-    ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(f64) = G_BITCAST [[SELECT4]](i64)
-    ; GFX6-NEXT: [[FNEG1:%[0-9]+]]:_(f64) = G_FNEG [[BITCAST6]]
+    ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(i64) = G_SELECT [[ICMP3]](s1), [[BITCAST4]], [[SELECT3]]
+    ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(f64) = G_BITCAST [[SELECT4]](i64)
+    ; GFX6-NEXT: [[FNEG1:%[0-9]+]]:_(f64) = G_FNEG [[BITCAST5]]
     ; GFX6-NEXT: [[FADD2:%[0-9]+]]:_(f64) = G_FADD [[UV1]], [[FNEG1]]
     ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f64) = G_FABS [[FADD2]]
     ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(i1) = G_FCMP floatpred(oge), [[FABS1]](f64), [[C8]]
     ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f64) = G_SELECT [[FCMP1]](i1), [[C9]], [[C10]]
-    ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT5]](f64)
-    ; GFX6-NEXT: [[BITCAST8:%[0-9]+]]:_(i64) = G_BITCAST [[UV1]](f64)
-    ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i64) = G_AND [[BITCAST7]], [[C12]]
-    ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(i64) = G_AND [[BITCAST8]], [[C11]]
+    ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(i64) = G_BITCAST [[SELECT5]](f64)
+    ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i64) = G_AND [[BITCAST6]], [[C12]]
+    ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(i64) = G_AND [[BITCAST4]], [[C11]]
     ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i64) = disjoint G_OR [[AND6]], [[AND7]]
-    ; GFX6-NEXT: [[BITCAST9:%[0-9]+]]:_(f64) = G_BITCAST [[OR1]](i64)
-    ; GFX6-NEXT: [[FADD3:%[0-9]+]]:_(f64) = G_FADD [[BITCAST6]], [[BITCAST9]]
+    ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(f64) = G_BITCAST [[OR1]](i64)
+    ; GFX6-NEXT: [[FADD3:%[0-9]+]]:_(f64) = G_FADD [[BITCAST5]], [[BITCAST7]]
     ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f64>) = G_BUILD_VECTOR [[FADD1]](f64), [[FADD3]](f64)
     ; GFX6-NEXT: $vgpr0_vgpr1_vgpr2_vgpr3 = COPY [[BUILD_VECTOR]](<2 x f64>)
     ;
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
index d761f2cd8a97e..58559584c4959 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.image.dim.a16.ll
@@ -113,9 +113,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX9-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX9-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX9-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX9-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 3 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -144,9 +143,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX10NSA-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX10NSA-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX10NSA-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX10NSA-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX10NSA-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX10NSA-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX10NSA-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX10NSA-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX10NSA-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX10NSA-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 1 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -175,9 +173,8 @@ define amdgpu_ps <4 x float> @load_2d(<8 x i32> inreg %rsrc, <2 x i16> %coords)
   ; GFX12-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX12-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX12-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX12-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX12-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX12-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX12-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX12-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
   ; GFX12-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX12-NEXT:   [[AMDGPU_INTRIN_IMAGE_LOAD:%[0-9]+]]:_(<4 x f32>) = G_AMDGPU_INTRIN_IMAGE_LOAD intrinsic(@llvm.amdgcn.image.load.2d), 15, [[BUILD_VECTOR1]](<2 x i16>), $noreg, [[BUILD_VECTOR]](<8 x i32>), 0, 0, 1 :: (dereferenceable load (<4 x f32>), addrspace 8)
@@ -214,12 +211,11 @@ define amdgpu_ps <4 x float> @load_3d(<8 x i32> inreg %rsrc, <2 x i16> %coords_l
   ; GFX9-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[LSHR:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR]](i32)
-  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY8]](<2 x i16>)
   ; GFX9-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 16
-  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C1]](i32)
+  ; GFX9-NEXT:   [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST]], [[C1]](i32)
   ; GFX9-NEXT:   [[TRUNC1:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR1]](i32)
-  ; GFX9-NEXT:   [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[COPY9]](<2 x i16>)
-  ; GFX9-NEXT:   [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST2]], [[C]](i32)
+  ; GFX9-NEXT:   [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY9]](<2 x i16>)
+  ; GFX9-NEXT:   [[LSHR2:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
   ; GFX9-NEXT:   [[TRUNC2:%[0-9]+]]:_(i16) = G_TRUNC [[LSHR2]](i32)
   ; GFX9-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x i16>) = G_BUILD_VECTOR [[TRUNC]](i16), [[TRUNC1]](i16)
   ; GFX9-NEXT:   [[DEF:%[0-9]+]]:_(i16) = G_IMPLICIT_DEF
@@ -252,12 +248,11 @@ define amdgpu_ps <4 x float> @load_3d(<8 x i32> inreg %rsrc, <2 x i16> %coords_l
   ; GFX10NSA-NEXT:   [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[COP...
[truncated]

@andrzej-densityai

Copy link
Copy Markdown
Contributor Author

@krzysz00 @petar-avramovic

@andrzej-densityai

Copy link
Copy Markdown
Contributor Author

Ping

@petar-avramovic

Copy link
Copy Markdown
Contributor

mostly LGTM but need to split into patches that do one thing

if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
if (MRI.getType(DstReg) == MRI.getType(TruncSrc))
auto DstType = MRI.getType(DstReg);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No auto

%1:_(i16) = G_TRUNC %0(i32)
%2:_(f32) = G_ANYEXT %1(i16)
$vgpr0 = COPY %2(f32)
... No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing end of file line error

@andrzej-densityai

Copy link
Copy Markdown
Contributor Author

mostly LGTM but need to split into patches that do one thing

Thanks. I'll split out the fix in the Combiner to another PR. Should I retain the two performance one-liners in this PR or split them into two PRs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants