[llvm] [SPIR-V] Allow NoUnsignedWrap decoration on OpShiftLeftLogical (PR #206155)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 05:16:43 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/206155
>From d1fafe5f83cd22febf214687d81ef4ef2af219c1 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 26 Jun 2026 21:03:34 +0200
Subject: [PATCH 1/2] [SPIR-V] Allow NoUnsignedWrap decoration on
OpShiftLeftLogical
Align the list of supported ops with spirv-val (shl is missing)
---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 2 ++
.../SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll | 7 +++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index 1a65e9635d855..386da52e009d7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -196,6 +196,8 @@ bool SPIRVInstrInfo::canUseNUW(const MachineInstr &MI) const {
case SPIRV::OpISubV:
case SPIRV::OpIMulS:
case SPIRV::OpIMulV:
+ case SPIRV::OpShiftLeftLogicalS:
+ case SPIRV::OpShiftLeftLogicalV:
return true;
default:
return false;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
index 216ca54a8abc9..5e4df6968865d 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_no_integer_wrap_decoration.ll
@@ -11,6 +11,7 @@
; CHECK-DAG: OpDecorate %[[#D:]] NoSignedWrap
; CHECK-DAG: OpDecorate %[[#E:]] NoUnsignedWrap
; CHECK-DAG: OpDecorate %[[#E]] NoSignedWrap
+; CHECK-DAG: OpDecorate %[[#F:]] NoUnsignedWrap
; CHECK-NOT: DAG-FENCE
@@ -23,7 +24,8 @@ define i32 @no_wrap_test(i32 %a, i32 %b) {
%c = mul nuw i32 %a, %b
%d = mul nsw i32 %a, %b
%e = add nuw nsw i32 %c, %d
- ret i32 %e
+ %f = shl nuw i32 %e, %b
+ ret i32 %f
}
; CHECK: OpFunction %[[#I32]] None %[[#FN]]
@@ -33,5 +35,6 @@ define i32 @no_wrap_test(i32 %a, i32 %b) {
; CHECK: %[[#C]] = OpIMul %[[#I32]] %[[#A]] %[[#B]]
; CHECK: %[[#D]] = OpIMul %[[#I32]] %[[#A]] %[[#B]]
; CHECK: %[[#E]] = OpIAdd %[[#I32]] %[[#C]] %[[#D]]
-; CHECK: OpReturnValue %[[#E]]
+; CHECK: %[[#F]] = OpShiftLeftLogical %[[#I32]] %[[#E]] %[[#B]]
+; CHECK: OpReturnValue %[[#F]]
; CHECK-NEXT: OpFunctionEnd
>From 00538e07e139237d61f277061a7aa0f568f944da Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 29 Jun 2026 14:16:33 +0200
Subject: [PATCH 2/2] Address review comments
---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 18 +-----------
llvm/lib/Target/SPIRV/SPIRVInstrInfo.h | 3 +-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 29 ++++++++++---------
3 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index 386da52e009d7..ab4719099339a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -171,7 +171,7 @@ bool SPIRVInstrInfo::canUseFastMathFlags(const MachineInstr &MI,
}
}
-bool SPIRVInstrInfo::canUseNSW(const MachineInstr &MI) const {
+bool SPIRVInstrInfo::canUseIntegerWrapDecoration(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case SPIRV::OpIAddS:
case SPIRV::OpIAddV:
@@ -188,22 +188,6 @@ bool SPIRVInstrInfo::canUseNSW(const MachineInstr &MI) const {
}
}
-bool SPIRVInstrInfo::canUseNUW(const MachineInstr &MI) const {
- switch (MI.getOpcode()) {
- case SPIRV::OpIAddS:
- case SPIRV::OpIAddV:
- case SPIRV::OpISubS:
- case SPIRV::OpISubV:
- case SPIRV::OpIMulS:
- case SPIRV::OpIMulV:
- case SPIRV::OpShiftLeftLogicalS:
- case SPIRV::OpShiftLeftLogicalV:
- return true;
- default:
- return false;
- }
-}
-
// Analyze the branching code at the end of MBB, returning
// true if it cannot be understood (e.g. it's a switch dispatch or isn't
// implemented for a target). Upon success, this returns false and returns
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
index 5d629283c5da7..87d389e3f58ec 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
@@ -38,8 +38,7 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
bool isAliasingInstr(const MachineInstr &MI) const;
bool canUseFastMathFlags(const MachineInstr &MI,
bool KHRFloatControls2) const;
- bool canUseNSW(const MachineInstr &MI) const;
- bool canUseNUW(const MachineInstr &MI) const;
+ bool canUseIntegerWrapDecoration(const MachineInstr &MI) const;
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index aed16fd785af8..2e87a0195a314 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -2773,20 +2773,21 @@ static void handleMIFlagDecoration(
MachineInstr &I, const SPIRVSubtarget &ST, const SPIRVInstrInfo &TII,
SPIRV::RequirementHandler &Reqs, const SPIRVGlobalRegistry *GR,
SPIRV::FPFastMathDefaultInfoVector &FPFastMathDefaultInfoVec) {
- if (I.getFlag(MachineInstr::MIFlag::NoSWrap) && TII.canUseNSW(I) &&
- getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
- SPIRV::Decoration::NoSignedWrap, ST, Reqs)
- .IsSatisfiable) {
- buildOpDecorate(I.getOperand(0).getReg(), I, TII,
- SPIRV::Decoration::NoSignedWrap, {});
- }
- if (I.getFlag(MachineInstr::MIFlag::NoUWrap) && TII.canUseNUW(I) &&
- getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
- SPIRV::Decoration::NoUnsignedWrap, ST,
- Reqs)
- .IsSatisfiable) {
- buildOpDecorate(I.getOperand(0).getReg(), I, TII,
- SPIRV::Decoration::NoUnsignedWrap, {});
+ if (TII.canUseIntegerWrapDecoration(I)) {
+ if (I.getFlag(MachineInstr::MIFlag::NoSWrap) &&
+ getSymbolicOperandRequirements(
+ SPIRV::OperandCategory::DecorationOperand,
+ SPIRV::Decoration::NoSignedWrap, ST, Reqs)
+ .IsSatisfiable)
+ buildOpDecorate(I.getOperand(0).getReg(), I, TII,
+ SPIRV::Decoration::NoSignedWrap, {});
+ if (I.getFlag(MachineInstr::MIFlag::NoUWrap) &&
+ getSymbolicOperandRequirements(
+ SPIRV::OperandCategory::DecorationOperand,
+ SPIRV::Decoration::NoUnsignedWrap, ST, Reqs)
+ .IsSatisfiable)
+ buildOpDecorate(I.getOperand(0).getReg(), I, TII,
+ SPIRV::Decoration::NoUnsignedWrap, {});
}
// In Kernel environments, FPFastMathMode on OpExtInst is valid per core
// spec. For other instruction types, SPV_KHR_float_controls2 is required.
More information about the llvm-commits
mailing list