[llvm] [HLSL][SPIRV] Update reversebits codegen for half types (PR #184936)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 10 20:08:42 PDT 2026
=?utf-8?q?João?= Saffran <joaosaffranllvm at gmail.com>,Joao Saffran
<joaosaffranllvm at gmail.com>,
=?utf-8?q?João?= Saffran <joaosaffranllvm at gmail.com>,Joao Saffran
<joaosaffranllvm at gmail.com>,Joao Saffran <joaosaffranllvm at gmail.com>,Joao
Saffran <joaosaffranllvm at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/184936 at github.com>
https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/184936
>From 3b597e52fe579240687db1aa72920c454bd54131 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 14:53:16 -0800
Subject: [PATCH 1/8] add 16 bit case
---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 21 ++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 7b4c047593a3a..bfaf861747612 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3081,11 +3081,30 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
+ Register OpReg = I.getOperand(1).getReg();
+
+ if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
+ SPIRVTypeInst IntType = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+ unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+ if (N > 1)
+ IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
+
+ OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+ unsigned ExtendOpcode =
+ sampledTypeIsSignedInteger(GR.getTypeForSPIRVType(ResType))
+ ? SPIRV::OpSConvert
+ : SPIRV::OpUConvert;
+ if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
+ ExtendOpcode))
+ return false;
+ ResType = IntType;
+ }
+
MachineBasicBlock &BB = *I.getParent();
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(1).getReg())
+ .addUse(OpReg)
.constrainAllUses(TII, TRI, RBI);
return true;
}
>From edb30c0ad4938969f4f71a48a4374fef622dcbf4 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 15:22:50 -0800
Subject: [PATCH 2/8] fix incorrect function usage & update test reversebits.ll
---
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 7 +++----
.../test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll | 11 +++++++++--
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index bfaf861747612..fd53bab28b4d8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3090,10 +3090,9 @@ bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
- unsigned ExtendOpcode =
- sampledTypeIsSignedInteger(GR.getTypeForSPIRVType(ResType))
- ? SPIRV::OpSConvert
- : SPIRV::OpUConvert;
+ unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+ ? SPIRV::OpSConvert
+ : SPIRV::OpUConvert;
if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
ExtendOpcode))
return false;
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
index 6571b2992fab3..77f24c72cffc6 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
@@ -3,16 +3,23 @@
; CHECK: OpMemoryModel Logical GLSL450
+;CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+;CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+
define noundef i32 @reversebits_i32(i32 noundef %a) {
entry:
-; CHECK: %[[#]] = OpBitReverse %[[#]] %[[#]]
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_32]]
+; CHECK-NOT: OpUConvert
+; CHECK: %[[#]] = OpBitReverse %[[#int_32]] %[[#param]]
%elt.bitreverse = call i32 @llvm.bitreverse.i32(i32 %a)
ret i32 %elt.bitreverse
}
define noundef i16 @reversebits_i16(i16 noundef %a) {
entry:
-; CHECK: %[[#]] = OpBitReverse %[[#]] %[[#]]
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_16]]
+; CHECK: %[[#conversion:]] = OpUConvert %[[#int_32]] %[[#param]]
+; CHECK-NEXT: %[[#]] = OpBitReverse %[[#int_32]] %[[#conversion]]
%elt.bitreverse = call i16 @llvm.bitreverse.i16(i16 %a)
ret i16 %elt.bitreverse
}
>From 3c0f0e494ff1fb110df41733414c6a345a3c04cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 17:14:27 -0800
Subject: [PATCH 3/8] add composite to shift
---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 68 ++++++++++++++-----
1 file changed, 52 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index fd53bab28b4d8..7b8dec6106142 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -188,6 +188,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
bool selectBitreverse(Register ResVReg, SPIRVTypeInst ResType,
MachineInstr &I) const;
+ bool selectBitreverse16(Register ResVReg, SPIRVTypeInst ResType,
+ MachineInstr &I) const;
+
bool selectBuildVector(Register ResVReg, SPIRVTypeInst ResType,
MachineInstr &I) const;
bool selectSplatVector(Register ResVReg, SPIRVTypeInst ResType,
@@ -3078,32 +3081,65 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
return true;
}
+bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
+ SPIRVTypeInst ResType,
+ MachineInstr &I) const {
+ SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+
+ unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+ if (N > 1)
+ Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
+
+ Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+ ? SPIRV::OpSConvert
+ : SPIRV::OpUConvert;
+ if (!selectOpWithSrcs(ExtReg, Int32Type, I, {I.getOperand(1).getReg()},
+ ExtendOpcode))
+ return false;
+
+ Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
+ return false;
+
+ Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+
+ Register ShiftConst;
+ if (N > 1) {
+ ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpConstantComposite))
+ .addDef(ShiftConst)
+ .addUse(GR.getSPIRVTypeID(Int32Type));
+ for (unsigned It = I.getNumExplicitDefs(); It < I.getNumExplicitOperands();
+ ++It)
+ MIB.addUse(ScalarShiftAmount);
+ MIB.constrainAllUses(TII, TRI, RBI);
+ } else {
+ ShiftConst = ScalarShiftAmount;
+ }
+
+ Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
+ N > 1 ? SPIRV::OpShiftRightLogicalV
+ : SPIRV::OpShiftRightLogicalS))
+ return false;
+
+ return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
+}
+
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
- Register OpReg = I.getOperand(1).getReg();
-
if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
- SPIRVTypeInst IntType = GR.getOrCreateSPIRVIntegerType(32, I, TII);
- unsigned N = GR.getScalarOrVectorComponentCount(ResType);
- if (N > 1)
- IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
-
- OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
- unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
- ? SPIRV::OpSConvert
- : SPIRV::OpUConvert;
- if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
- ExtendOpcode))
- return false;
- ResType = IntType;
+ return selectBitreverse16(ResVReg, ResType, I);
}
MachineBasicBlock &BB = *I.getParent();
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(OpReg)
+ .addUse(I.getOperand(1).getReg())
.constrainAllUses(TII, TRI, RBI);
return true;
}
>From 1f4c76b49e9a528c02790d84abd9aa9381f2a073 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 17:36:31 -0800
Subject: [PATCH 4/8] fix composite logic
---
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 7b8dec6106142..41bbb10da8e74 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3085,6 +3085,7 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+ Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
unsigned N = GR.getScalarOrVectorComponentCount(ResType);
if (N > 1)
@@ -3102,8 +3103,6 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
return false;
- Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
-
Register ShiftConst;
if (N > 1) {
ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
@@ -3111,8 +3110,7 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
TII.get(SPIRV::OpConstantComposite))
.addDef(ShiftConst)
.addUse(GR.getSPIRVTypeID(Int32Type));
- for (unsigned It = I.getNumExplicitDefs(); It < I.getNumExplicitOperands();
- ++It)
+ for (unsigned It = 0; It < N; ++It)
MIB.addUse(ScalarShiftAmount);
MIB.constrainAllUses(TII, TRI, RBI);
} else {
>From b63d635555dc90b2e6d8e5eac42c2806bbff07c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 18:21:45 -0800
Subject: [PATCH 5/8] update test
---
.../SPIRV/hlsl-intrinsics/reversebits.ll | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
index 77f24c72cffc6..c1c7210b90f6a 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
@@ -5,12 +5,18 @@
;CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
;CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+;CHECK-DAG: %[[#vec_int_32:]] = OpTypeVector %[[#int_32]] 2
+;CHECK-DAG: %[[#vec_int_16:]] = OpTypeVector %[[#int_16]] 2
+
+;CHECK-DAG: %[[#const_16:]] = OpConstant %[[#int_32]] 16
+;CHECK-DAG: %[[#composite:]] = OpConstantComposite %[[#vec_int_32]] %[[#const_16]] %[[#const_16]]
define noundef i32 @reversebits_i32(i32 noundef %a) {
entry:
; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_32]]
; CHECK-NOT: OpUConvert
; CHECK: %[[#]] = OpBitReverse %[[#int_32]] %[[#param]]
+; CHECK-NOT: OpShiftRightLogical
%elt.bitreverse = call i32 @llvm.bitreverse.i32(i32 %a)
ret i32 %elt.bitreverse
}
@@ -19,10 +25,25 @@ define noundef i16 @reversebits_i16(i16 noundef %a) {
entry:
; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_16]]
; CHECK: %[[#conversion:]] = OpUConvert %[[#int_32]] %[[#param]]
-; CHECK-NEXT: %[[#]] = OpBitReverse %[[#int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#bitrev:]] = OpBitReverse %[[#int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#shift:]] = OpShiftRightLogical %[[#int_32]] %[[#bitrev]] %[[#const_16]]
+; CHECK-NEXT: %[[#]] = OpUConvert %[[#int_16]] %[[#shift]]
%elt.bitreverse = call i16 @llvm.bitreverse.i16(i16 %a)
ret i16 %elt.bitreverse
}
+define noundef <2 x i16> @reversebits_veci16(<2 x i16> noundef %a) {
+entry:
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#vec_int_16]]
+; CHECK: %[[#conversion:]] = OpUConvert %[[#vec_int_32]] %[[#param]]
+; CHECK-NEXT: %[[#bitrev:]] = OpBitReverse %[[#vec_int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#shift:]] = OpShiftRightLogical %[[#vec_int_32]] %[[#bitrev]] %[[#composite]]
+; CHECK-NEXT: %[[#]] = OpUConvert %[[#vec_int_16]] %[[#shift]]
+ %elt.bitreverse = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
+ ret <2 x i16> %elt.bitreverse
+}
+
+
declare i16 @llvm.bitreverse.i16(i16)
declare i32 @llvm.bitreverse.i32(i32)
+declare <2 x i16> @llvm.bitreverse.v2i16(<2 x i16>)
>From 251a7c965e51fb7500302f00f5f6002d3a1525fe Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 9 Mar 2026 16:18:13 -0700
Subject: [PATCH 6/8] create a single function to emit bitreverse
---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 44 ++++++++++++++-----
1 file changed, 32 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 41bbb10da8e74..887a7faa50589 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -189,7 +189,10 @@ class SPIRVInstructionSelector : public InstructionSelector {
MachineInstr &I) const;
bool selectBitreverse16(Register ResVReg, SPIRVTypeInst ResType,
- MachineInstr &I) const;
+ MachineInstr &I, Register Op) const;
+
+ bool selectBitreverse32(Register ResVReg, SPIRVTypeInst ResType,
+ MachineInstr &I, Register Op) const;
bool selectBuildVector(Register ResVReg, SPIRVTypeInst ResType,
MachineInstr &I) const;
@@ -3083,7 +3086,8 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
SPIRVTypeInst ResType,
- MachineInstr &I) const {
+ MachineInstr &I,
+ Register Op) const {
SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
@@ -3095,12 +3099,14 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
? SPIRV::OpSConvert
: SPIRV::OpUConvert;
- if (!selectOpWithSrcs(ExtReg, Int32Type, I, {I.getOperand(1).getReg()},
+ // Converts the i16 input to i32 (or vector of i32)
+ if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op},
ExtendOpcode))
return false;
Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
- if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
+ // Perform bitreverse on the i32 value
+ if(!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
return false;
Register ShiftConst;
@@ -3118,30 +3124,44 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
}
Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+
+ // Shift the bit-reversed value to get the final result.
if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
N > 1 ? SPIRV::OpShiftRightLogicalV
: SPIRV::OpShiftRightLogicalS))
return false;
-
+
+ // Finally, convert the result back to i16 (or vector of i16).
return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
}
-bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
+bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
SPIRVTypeInst ResType,
- MachineInstr &I) const {
- if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
- return selectBitreverse16(ResVReg, ResType, I);
- }
-
+ MachineInstr &I,
+ Register Op) const {
MachineBasicBlock &BB = *I.getParent();
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(1).getReg())
+ .addUse(Op)
.constrainAllUses(TII, TRI, RBI);
return true;
}
+
+bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
+ SPIRVTypeInst ResType,
+ MachineInstr &I) const {
+ Register OpReg = I.getOperand(1).getReg();
+ SPIRVTypeInst OpType = GR.getSPIRVTypeForVReg(OpReg);
+ switch(GR.getScalarOrVectorBitWidth(OpType)) {
+ case 16:
+ return selectBitreverse16(ResVReg, ResType, I, OpReg);
+ default:
+ return selectBitreverse32(ResVReg, ResType, I, OpReg);
+ }
+}
+
bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
>From b9b95abbe03a462c3f091895b4e423288466a91b Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 9 Mar 2026 16:55:15 -0700
Subject: [PATCH 7/8] format
---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 22 +++++++++----------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 887a7faa50589..a7a3f877f4eb5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3086,7 +3086,7 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
SPIRVTypeInst ResType,
- MachineInstr &I,
+ MachineInstr &I,
Register Op) const {
SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
@@ -3099,14 +3099,13 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
? SPIRV::OpSConvert
: SPIRV::OpUConvert;
- // Converts the i16 input to i32 (or vector of i32)
- if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op},
- ExtendOpcode))
+ // Converts the i16 input to i32 (or vector of i32)
+ if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
return false;
Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
// Perform bitreverse on the i32 value
- if(!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
+ if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
return false;
Register ShiftConst;
@@ -3125,20 +3124,20 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
- // Shift the bit-reversed value to get the final result.
+ // Shift the bit-reversed value to get the final result.
if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
N > 1 ? SPIRV::OpShiftRightLogicalV
: SPIRV::OpShiftRightLogicalS))
return false;
-
+
// Finally, convert the result back to i16 (or vector of i16).
return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
}
bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
- SPIRVTypeInst ResType,
- MachineInstr &I,
- Register Op) const {
+ SPIRVTypeInst ResType,
+ MachineInstr &I,
+ Register Op) const {
MachineBasicBlock &BB = *I.getParent();
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
.addDef(ResVReg)
@@ -3148,13 +3147,12 @@ bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
return true;
}
-
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
Register OpReg = I.getOperand(1).getReg();
SPIRVTypeInst OpType = GR.getSPIRVTypeForVReg(OpReg);
- switch(GR.getScalarOrVectorBitWidth(OpType)) {
+ switch (GR.getScalarOrVectorBitWidth(OpType)) {
case 16:
return selectBitreverse16(ResVReg, ResType, I, OpReg);
default:
>From f86cb1a5b76b0f6f7691f533415a60a932bb19b6 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Tue, 10 Mar 2026 20:08:14 -0700
Subject: [PATCH 8/8] refactor for readability
---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 53 ++++++++++---------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index a7a3f877f4eb5..a200cb45fd440 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3089,45 +3089,46 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
MachineInstr &I,
Register Op) const {
SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
- Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+ Register ShiftConst = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+ unsigned ShiftOp = SPIRV::OpShiftRightLogicalS;
- unsigned N = GR.getScalarOrVectorComponentCount(ResType);
- if (N > 1)
- Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
-
- Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
- unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
- ? SPIRV::OpSConvert
- : SPIRV::OpUConvert;
- // Converts the i16 input to i32 (or vector of i32)
- if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
- return false;
+ const unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+ const unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+ ? SPIRV::OpSConvert
+ : SPIRV::OpUConvert;
- Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
- // Perform bitreverse on the i32 value
- if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
- return false;
-
- Register ShiftConst;
if (N > 1) {
- ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
+ ShiftOp = SPIRV::OpShiftRightLogicalV;
+
+ // Vector shifts require a composite constant
+ const Register CompositeReg =
+ MRI->createVirtualRegister(GR.getRegClass(Int32Type));
auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(SPIRV::OpConstantComposite))
- .addDef(ShiftConst)
+ .addDef(CompositeReg)
.addUse(GR.getSPIRVTypeID(Int32Type));
for (unsigned It = 0; It < N; ++It)
- MIB.addUse(ScalarShiftAmount);
+ MIB.addUse(ShiftConst);
MIB.constrainAllUses(TII, TRI, RBI);
- } else {
- ShiftConst = ScalarShiftAmount;
+
+ ShiftConst = CompositeReg;
}
- Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ // Converts the i16 input to i32 (or vector of i32)
+ Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
+ return false;
+
+ // Perform bitreverse on the i32 value
+ Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+ if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
+ return false;
// Shift the bit-reversed value to get the final result.
+ Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
- N > 1 ? SPIRV::OpShiftRightLogicalV
- : SPIRV::OpShiftRightLogicalS))
+ ShiftOp))
return false;
// Finally, convert the result back to i16 (or vector of i16).
More information about the llvm-commits
mailing list