[llvm-branch-commits] [llvm] [GlobalISel] Lower bytecast in IRTranslator (PR #221887)
Anshil Gandhi via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 7 23:05:39 PDT 2026
https://github.com/gandhi56 updated https://github.com/llvm/llvm-project/pull/221887
>From 0ffb307013756865072c885afa3943f091d756d3 Mon Sep 17 00:00:00 2001
From: Anshil Gandhi <Anshil.Gandhi at amd.com>
Date: Mon, 7 Sep 2026 07:45:49 -0500
Subject: [PATCH] [GlobalISel] Lower bytecast in IRTranslator
Add translateByteCast and move byte-specific cast lowering out of
translateBitCast. Byte-pointer crossings use G_INTTOPTR/G_PTRTOINT; other
byte casts reuse the existing G_BITCAST/COPY paths.
Co-authored-by: Cursor <cursoragent at cursor.com>
---
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 27 ++++++++++-----
.../AMDGPU/GlobalISel/amdgpu-irtranslator.ll | 34 +++++++++----------
2 files changed, 36 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 534848466b643..ef144eee8aa47 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2357,12 +2357,28 @@ bool IRTranslatorImpl::translateBitCast(const User &U,
return translateCopy(U, *U.getOperand(0), MIRBuilder);
}
+ return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
+}
+
+bool IRTranslatorImpl::translateByteCast(const User &U,
+ MachineIRBuilder &MIRBuilder) {
+ Type *SrcTy = U.getOperand(0)->getType();
+ Type *DstTy = U.getType();
+
+ // If we're casting to the source type, we can reuse the source vreg.
+ if (getLLTForType(*SrcTy, *DL) == getLLTForType(*DstTy, *DL)) {
+ if (isa<ConstantInt>(U.getOperand(0)))
+ return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
+ MIRBuilder);
+ return translateCopy(U, *U.getOperand(0), MIRBuilder);
+ }
+
// Only the scalar byte<->ptr crossing is redirected to G_INTTOPTR/G_PTRTOINT,
// which is the well-typed MIR shape for that boundary. Vector byte<->ptr
// (e.g. <N x b32> -> ptr produced by mixed-type load coalescing) and other
- // legacy ptr/non-ptr IR bitcasts (AMDGPU iN<->p3 kernarg packing, etc.)
- // keep their historical G_BITCAST lowering — G_INTTOPTR has no vector-src
- // -> scalar-ptr form, and downstream passes already handle G_BITCAST.
+ // legacy ptr/non-ptr IR bytecasts keep their historical G_BITCAST lowering —
+ // G_INTTOPTR has no vector-src -> scalar-ptr form, and downstream passes
+ // already handle G_BITCAST.
if (DstTy->isPointerTy() && SrcTy->isByteTy())
return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
if (SrcTy->isPointerTy() && DstTy->isByteTy())
@@ -2371,11 +2387,6 @@ bool IRTranslatorImpl::translateBitCast(const User &U,
return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
}
-bool IRTranslatorImpl::translateByteCast(const User &U,
- MachineIRBuilder &MIRBuilder) {
- return translateBitCast(U, MIRBuilder);
-}
-
bool IRTranslatorImpl::translateCast(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) {
if (!mayTranslateUserTypes(U))
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll
index 672aec2551c03..41dbc1990f91f 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll
@@ -37,10 +37,10 @@ define void @byte_constant(ptr addrspace(1) %p) {
ret void
}
-; bitcast b64 -> ptr crosses the pointer/non-pointer boundary, which
+; bytecast b64 -> ptr crosses the pointer/non-pointer boundary, which
; G_BITCAST cannot express; lower it as G_INTTOPTR.
-define void @bitcast_b64_to_p1(b64 %b) {
- ; CHECK-LABEL: name: bitcast_b64_to_p1
+define void @bytecast_b64_to_p1(b64 %b) {
+ ; CHECK-LABEL: name: bytecast_b64_to_p1
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $vgpr0, $vgpr1
; CHECK-NEXT: {{ $}}
@@ -51,14 +51,14 @@ define void @bitcast_b64_to_p1(b64 %b) {
; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p1) = G_INTTOPTR [[MV]](i64)
; CHECK-NEXT: G_STORE [[C]](i64), [[INTTOPTR]](p1) :: (store (i64) into %ir.p, addrspace 1)
; CHECK-NEXT: SI_RETURN
- %p = bitcast b64 %b to ptr addrspace(1)
+ %p = bytecast b64 %b to ptr addrspace(1)
store i64 0, ptr addrspace(1) %p
ret void
}
; Inverse direction lowers to G_PTRTOINT.
-define void @bitcast_p1_to_b64(ptr addrspace(1) %p) {
- ; CHECK-LABEL: name: bitcast_p1_to_b64
+define void @bytecast_p1_to_b64(ptr addrspace(1) %p) {
+ ; CHECK-LABEL: name: bytecast_p1_to_b64
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $vgpr0, $vgpr1
; CHECK-NEXT: {{ $}}
@@ -69,14 +69,14 @@ define void @bitcast_p1_to_b64(ptr addrspace(1) %p) {
; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(i64) = G_PTRTOINT [[MV]](p1)
; CHECK-NEXT: G_STORE [[PTRTOINT]](i64), [[DEF]](p0) :: (store (i64) into `ptr poison`)
; CHECK-NEXT: SI_RETURN
- %b = bitcast ptr addrspace(1) %p to b64
+ %b = bytecast ptr addrspace(1) %p to b64
store b64 %b, ptr poison
ret void
}
-; Byte and same-sized integer share an LLT, so this bitcast collapses to a copy.
-define void @bitcast_b64_to_i64(b64 %b, ptr addrspace(1) %p) {
- ; CHECK-LABEL: name: bitcast_b64_to_i64
+; Byte and same-sized integer share an LLT, so this bytecast collapses to a copy.
+define void @bytecast_b64_to_i64(b64 %b, ptr addrspace(1) %p) {
+ ; CHECK-LABEL: name: bytecast_b64_to_i64
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3
; CHECK-NEXT: {{ $}}
@@ -88,14 +88,14 @@ define void @bitcast_b64_to_i64(b64 %b, ptr addrspace(1) %p) {
; CHECK-NEXT: [[MV1:%[0-9]+]]:_(p1) = G_MERGE_VALUES [[COPY2]](i32), [[COPY3]](i32)
; CHECK-NEXT: G_STORE [[MV]](i64), [[MV1]](p1) :: (store (i64) into %ir.p, addrspace 1)
; CHECK-NEXT: SI_RETURN
- %i = bitcast b64 %b to i64
+ %i = bytecast b64 %b to i64
store i64 %i, ptr addrspace(1) %p
ret void
}
; Same-LLT direction: integer to byte is also a copy.
-define void @bitcast_i64_to_b64(i64 %i, ptr addrspace(1) %p) {
- ; CHECK-LABEL: name: bitcast_i64_to_b64
+define void @bytecast_i64_to_b64(i64 %i, ptr addrspace(1) %p) {
+ ; CHECK-LABEL: name: bytecast_i64_to_b64
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3
; CHECK-NEXT: {{ $}}
@@ -107,15 +107,15 @@ define void @bitcast_i64_to_b64(i64 %i, ptr addrspace(1) %p) {
; CHECK-NEXT: [[MV1:%[0-9]+]]:_(p1) = G_MERGE_VALUES [[COPY2]](i32), [[COPY3]](i32)
; CHECK-NEXT: G_STORE [[MV]](i64), [[MV1]](p1) :: (store (i64) into %ir.p, addrspace 1)
; CHECK-NEXT: SI_RETURN
- %b = bitcast i64 %i to b64
+ %b = bytecast i64 %i to b64
store b64 %b, ptr addrspace(1) %p
ret void
}
; Byte to floating point: distinct LLTs in extended mode, equal in default mode.
; AMDGPU runs in default mode, so this collapses to a copy.
-define void @bitcast_b64_to_double(b64 %b, ptr addrspace(1) %p) {
- ; CHECK-LABEL: name: bitcast_b64_to_double
+define void @bytecast_b64_to_double(b64 %b, ptr addrspace(1) %p) {
+ ; CHECK-LABEL: name: bytecast_b64_to_double
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3
; CHECK-NEXT: {{ $}}
@@ -128,7 +128,7 @@ define void @bitcast_b64_to_double(b64 %b, ptr addrspace(1) %p) {
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(f64) = G_BITCAST [[MV]](i64)
; CHECK-NEXT: G_STORE [[BITCAST]](f64), [[MV1]](p1) :: (store (f64) into %ir.p, addrspace 1)
; CHECK-NEXT: SI_RETURN
- %d = bitcast b64 %b to double
+ %d = bytecast b64 %b to double
store double %d, ptr addrspace(1) %p
ret void
}
More information about the llvm-branch-commits
mailing list