[llvm] [SPIR-V] Fix incorrect bitwise instructions applied to the bool type (PR #85929)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 20 06:30:59 PDT 2024
https://github.com/VyacheslavLevytskyy created https://github.com/llvm/llvm-project/pull/85929
This PR ensures that LLVM IR bitwise instructions result in logical SPIR-V instructions when applied to i1 type.
>From 87bf3a8397341766283a7924d9b72ec061924d30 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Wed, 20 Mar 2024 06:29:11 -0700
Subject: [PATCH] ensure that LLVM IR bitwise instructions result in logical
SPIR-V instructions when applied to i1 type
---
llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 20 ++++++
.../CodeGen/SPIRV/instructions/bitwise-i1.ll | 69 +++++++++++++++++++
2 files changed, 89 insertions(+)
create mode 100644 llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
index e6e9131d8dc28f..55b4c47c197dab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
@@ -145,6 +145,26 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const {
validatePtrTypes(STI, MRI, GR, MI,
GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg()), 0);
break;
+ // ensure that LLVM IR bitwise instructions result in logical SPIR-V
+ // instructions when applied to bool type
+ case SPIRV::OpBitwiseOrS:
+ case SPIRV::OpBitwiseOrV:
+ if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
+ SPIRV::OpTypeBool))
+ MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalOr));
+ break;
+ case SPIRV::OpBitwiseAndS:
+ case SPIRV::OpBitwiseAndV:
+ if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
+ SPIRV::OpTypeBool))
+ MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalAnd));
+ break;
+ case SPIRV::OpBitwiseXorS:
+ case SPIRV::OpBitwiseXorV:
+ if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
+ SPIRV::OpTypeBool))
+ MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual));
+ break;
}
}
}
diff --git a/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll b/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll
new file mode 100644
index 00000000000000..8d3657b36454bf
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll
@@ -0,0 +1,69 @@
+; This test ensures that LLVM IR bitwise instructions result in logical SPIR-V instructions
+; when applied to i1 type
+
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#Char:]] = OpTypeInt 8 0
+; CHECK-DAG: %[[#Vec2Char:]] = OpTypeVector %[[#Char]] 2
+; CHECK-DAG: %[[#Bool:]] = OpTypeBool
+; CHECK-DAG: %[[#Vec2Bool:]] = OpTypeVector %[[#Bool]] 2
+
+; CHECK: OpBitwiseAnd %[[#Char]]
+; CHECK: OpBitwiseOr %[[#Char]]
+; CHECK: OpBitwiseXor %[[#Char]]
+; CHECK: OpBitwiseAnd %[[#Vec2Char]]
+; CHECK: OpBitwiseOr %[[#Vec2Char]]
+; CHECK: OpBitwiseXor %[[#Vec2Char]]
+
+; CHECK: OpLogicalAnd %[[#Bool]]
+
+; CHECK: OpLogicalAnd %[[#Bool]]
+; CHECK: OpLogicalOr %[[#Bool]]
+; CHECK: OpLogicalNotEqual %[[#Bool]]
+; CHECK: OpLogicalAnd %[[#Vec2Bool]]
+; CHECK: OpLogicalOr %[[#Vec2Bool]]
+; CHECK: OpLogicalNotEqual %[[#Vec2Bool]]
+
+define void @test1(i8 noundef %arg1, i8 noundef %arg2) {
+ %cond1 = and i8 %arg1, %arg2
+ %cond2 = or i8 %arg1, %arg2
+ %cond3 = xor i8 %arg1, %arg2
+ ret void
+}
+
+define void @test1v(<2 x i8> noundef %arg1, <2 x i8> noundef %arg2) {
+ %cond1 = and <2 x i8> %arg1, %arg2
+ %cond2 = or <2 x i8> %arg1, %arg2
+ %cond3 = xor <2 x i8> %arg1, %arg2
+ ret void
+}
+
+define void @test2(float noundef %real, float noundef %imag) {
+entry:
+ %realabs = tail call spir_func noundef float @_Z16__spirv_ocl_fabsf(float noundef %real)
+ %cond1 = fcmp oeq float %realabs, 1.000000e+00
+ %cond2 = fcmp oeq float %imag, 0.000000e+00
+ %cond3 = and i1 %cond1, %cond2
+ br i1 %cond3, label %midlbl, label %cleanup
+midlbl:
+ br label %cleanup
+cleanup:
+ ret void
+}
+
+define void @test3(i1 noundef %arg1, i1 noundef %arg2) {
+ %cond1 = and i1 %arg1, %arg2
+ %cond2 = or i1 %arg1, %arg2
+ %cond3 = xor i1 %arg1, %arg2
+ ret void
+}
+
+define void @test3v(<2 x i1> noundef %arg1, <2 x i1> noundef %arg2) {
+ %cond1 = and <2 x i1> %arg1, %arg2
+ %cond2 = or <2 x i1> %arg1, %arg2
+ %cond3 = xor <2 x i1> %arg1, %arg2
+ ret void
+}
+
+declare dso_local spir_func noundef float @_Z16__spirv_ocl_fabsf(float noundef)
More information about the llvm-commits
mailing list