-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SPIR-V] Emit Alignment decoration for alloca instructions and improve type inference #118520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPIR-V] Emit Alignment decoration for alloca instructions and improve type inference #118520
Conversation
@llvm/pr-subscribers-llvm-ir Author: Vyacheslav Levytskyy (VyacheslavLevytskyy) ChangesThe SPIR-V Backend didn't generate Alignment decoration for alloca instructions. This PR is to fix this. Full diff: https://github.com/llvm/llvm-project/pull/118520.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 17b70062e58fa9..1ae3129774e507 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -36,8 +36,8 @@ let TargetPrefix = "spv" in {
def int_spv_selection_merge : Intrinsic<[], [llvm_vararg_ty]>;
def int_spv_cmpxchg : Intrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_vararg_ty]>;
def int_spv_unreachable : Intrinsic<[], []>;
- def int_spv_alloca : Intrinsic<[llvm_any_ty], []>;
- def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty]>;
+ def int_spv_alloca : Intrinsic<[llvm_any_ty], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
+ def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty, llvm_i8_ty], [ImmArg<ArgIndex<1>>]>;
def int_spv_undef : Intrinsic<[llvm_i32_ty], []>;
def int_spv_inline_asm : Intrinsic<[], [llvm_metadata_ty, llvm_metadata_ty, llvm_vararg_ty]>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index f45bdfc7aacb72..7e8c669e676fb5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1713,9 +1713,12 @@ Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
TrackConstants = false;
Type *PtrTy = I.getType();
auto *NewI =
- ArraySize ? B.CreateIntrinsic(Intrinsic::spv_alloca_array,
- {PtrTy, ArraySize->getType()}, {ArraySize})
- : B.CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy}, {});
+ ArraySize
+ ? B.CreateIntrinsic(Intrinsic::spv_alloca_array,
+ {PtrTy, ArraySize->getType()},
+ {ArraySize, B.getInt8(I.getAlign().value())})
+ : B.CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy},
+ {B.getInt8(I.getAlign().value())});
replaceAllUsesWithAndErase(B, &I, NewI);
return NewI;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 3547ac66430a87..3a98b74b3d6757 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3298,12 +3298,17 @@ bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
// there was an allocation size parameter to the allocation instruction
// that is not 1
MachineBasicBlock &BB = *I.getParent();
- return BuildMI(BB, I, I.getDebugLoc(),
- TII.get(SPIRV::OpVariableLengthArrayINTEL))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(2).getReg())
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(BB, I, I.getDebugLoc(),
+ TII.get(SPIRV::OpVariableLengthArrayINTEL))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(3).getImm();
+ buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::Alignment, {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
@@ -3312,12 +3317,18 @@ bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
// Change order of instructions if needed: all OpVariable instructions in a
// function must be the first instructions in the first block
auto It = getOpVariableMBBIt(I);
- return BuildMI(*It->getParent(), It, It->getDebugLoc(),
- TII.get(SPIRV::OpVariable))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(*It->getParent(), It, It->getDebugLoc(),
+ TII.get(SPIRV::OpVariable))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(2).getImm();
+ buildOpDecorate(ResVReg, *It, TII, SPIRV::Decoration::Alignment,
+ {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectBranch(MachineInstr &I) const {
|
@llvm/pr-subscribers-backend-spir-v Author: Vyacheslav Levytskyy (VyacheslavLevytskyy) ChangesThe SPIR-V Backend didn't generate Alignment decoration for alloca instructions. This PR is to fix this. Full diff: https://github.com/llvm/llvm-project/pull/118520.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 17b70062e58fa9..1ae3129774e507 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -36,8 +36,8 @@ let TargetPrefix = "spv" in {
def int_spv_selection_merge : Intrinsic<[], [llvm_vararg_ty]>;
def int_spv_cmpxchg : Intrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_vararg_ty]>;
def int_spv_unreachable : Intrinsic<[], []>;
- def int_spv_alloca : Intrinsic<[llvm_any_ty], []>;
- def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty]>;
+ def int_spv_alloca : Intrinsic<[llvm_any_ty], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
+ def int_spv_alloca_array : Intrinsic<[llvm_any_ty], [llvm_anyint_ty, llvm_i8_ty], [ImmArg<ArgIndex<1>>]>;
def int_spv_undef : Intrinsic<[llvm_i32_ty], []>;
def int_spv_inline_asm : Intrinsic<[], [llvm_metadata_ty, llvm_metadata_ty, llvm_vararg_ty]>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index f45bdfc7aacb72..7e8c669e676fb5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1713,9 +1713,12 @@ Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
TrackConstants = false;
Type *PtrTy = I.getType();
auto *NewI =
- ArraySize ? B.CreateIntrinsic(Intrinsic::spv_alloca_array,
- {PtrTy, ArraySize->getType()}, {ArraySize})
- : B.CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy}, {});
+ ArraySize
+ ? B.CreateIntrinsic(Intrinsic::spv_alloca_array,
+ {PtrTy, ArraySize->getType()},
+ {ArraySize, B.getInt8(I.getAlign().value())})
+ : B.CreateIntrinsic(Intrinsic::spv_alloca, {PtrTy},
+ {B.getInt8(I.getAlign().value())});
replaceAllUsesWithAndErase(B, &I, NewI);
return NewI;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 3547ac66430a87..3a98b74b3d6757 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3298,12 +3298,17 @@ bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
// there was an allocation size parameter to the allocation instruction
// that is not 1
MachineBasicBlock &BB = *I.getParent();
- return BuildMI(BB, I, I.getDebugLoc(),
- TII.get(SPIRV::OpVariableLengthArrayINTEL))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(2).getReg())
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(BB, I, I.getDebugLoc(),
+ TII.get(SPIRV::OpVariableLengthArrayINTEL))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(3).getImm();
+ buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::Alignment, {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
@@ -3312,12 +3317,18 @@ bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
// Change order of instructions if needed: all OpVariable instructions in a
// function must be the first instructions in the first block
auto It = getOpVariableMBBIt(I);
- return BuildMI(*It->getParent(), It, It->getDebugLoc(),
- TII.get(SPIRV::OpVariable))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(*It->getParent(), It, It->getDebugLoc(),
+ TII.get(SPIRV::OpVariable))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(2).getImm();
+ buildOpDecorate(ResVReg, *It, TII, SPIRV::Decoration::Alignment,
+ {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectBranch(MachineInstr &I) const {
|
5c14dc3
to
eb7849f
Compare
This PR is to fix the following issues: