Skip to content

Commit 8cf4bd9

Browse files
improve instruction selection
1 parent 10ab51c commit 8cf4bd9

File tree

3 files changed

+67
-74
lines changed

3 files changed

+67
-74
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class SPIRVInstructionSelector : public InstructionSelector {
6161
/// We need to keep track of the number we give to anonymous global values to
6262
/// generate the same name every time when this is needed.
6363
mutable DenseMap<const GlobalValue *, unsigned> UnnamedGlobalIDs;
64+
SmallPtrSet<MachineInstr *, 8> DeadMIs;
6465

6566
public:
6667
SPIRVInstructionSelector(const SPIRVTargetMachine &TM,
@@ -382,6 +383,24 @@ static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI);
382383
// Defined in SPIRVLegalizerInfo.cpp.
383384
extern bool isTypeFoldingSupported(unsigned Opcode);
384385

386+
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
387+
for (const auto &MO : MI.all_defs()) {
388+
Register Reg = MO.getReg();
389+
if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
390+
return false;
391+
}
392+
if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE || MI.isFakeUse() ||
393+
MI.isLifetimeMarker())
394+
return false;
395+
if (MI.isPHI())
396+
return true;
397+
if (MI.mayStore() || MI.isCall() ||
398+
(MI.mayLoad() && MI.hasOrderedMemoryRef()) || MI.isPosition() ||
399+
MI.isDebugInstr() || MI.isTerminator() || MI.isJumpTableDebugInfo())
400+
return false;
401+
return true;
402+
}
403+
385404
bool SPIRVInstructionSelector::select(MachineInstr &I) {
386405
resetVRegsType(*I.getParent()->getParent());
387406

@@ -404,8 +423,11 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
404423
}
405424
});
406425
assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
407-
if (Res)
426+
if (Res) {
427+
if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
428+
DeadMIs.insert(Def);
408429
return Res;
430+
}
409431
}
410432
MRI->setRegClass(SrcReg, MRI->getRegClass(DstReg));
411433
MRI->replaceRegWith(SrcReg, DstReg);
@@ -418,6 +440,15 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
418440
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
419441
}
420442

443+
if (DeadMIs.contains(&I)) {
444+
// if the instruction has been already made dead by folding it away
445+
// erase it
446+
LLVM_DEBUG(dbgs() << "Instruction is folded and dead.\n");
447+
salvageDebugInfo(*MRI, I);
448+
I.eraseFromParent();
449+
return true;
450+
}
451+
421452
if (I.getNumOperands() != I.getNumExplicitOperands()) {
422453
LLVM_DEBUG(errs() << "Generic instr has unexpected implicit operands\n");
423454
return false;

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
228228
.legalFor(allFloatScalarsAndVectors);
229229

230230
getActionDefinitionsBuilder(G_STRICT_FLDEXP)
231-
.legalForCartesianProduct(allFloatScalarsAndVectors,
232-
allFloatScalarsAndVectors);
231+
.legalForCartesianProduct(allFloatScalarsAndVectors, allIntScalars);
233232

234233
getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
235234
.legalForCartesianProduct(allIntScalarsAndVectors,
Lines changed: 34 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,44 @@
1-
; Adapted from https://github.com/KhronosGroup/SPIRV-LLVM-Translator/tree/main/test/llvm-intrinsics
2-
31
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
42
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
53

6-
; CHECK: OpName %[[#ad:]] "add"
7-
; CHECK: OpName %[[#di:]] "div"
8-
; CHECK: OpName %[[#su:]] "sub"
9-
; CHECK: OpName %[[#mu:]] "mul"
10-
11-
; CHECK-NOT: OpDecorate %[[#]] FPRoundingMode
12-
13-
; CHECK-DAG: OpDecorate %[[#ad]] FPRoundingMode 0
14-
; CHECK-DAG: OpDecorate %[[#di]] FPRoundingMode 1
15-
; CHECK-DAG: OpDecorate %[[#su]] FPRoundingMode 2
16-
; CHECK-DAG: OpDecorate %[[#mu]] FPRoundingMode 3
17-
18-
; CHECK-NOT: OpDecorate %[[#]] FPRoundingMode
19-
20-
; CHECK: OpFAdd %[[#]] %[[#ad]]
21-
; CHECK: OpFDiv %[[#]] %[[#di]]
22-
; CHECK: OpFSub %[[#]] %[[#su]]
23-
; CHECK: OpFMul %[[#]] %[[#mu]]
24-
; CHECK: OpExtInst %[[#]] %[[#]] %[[#]] fma
4+
; CHECK-DAG: OpName %[[#r1:]] "r1"
5+
; CHECK-DAG: OpName %[[#r2:]] "r2"
6+
; CHECK-DAG: OpName %[[#r3:]] "r3"
7+
; CHECK-DAG: OpName %[[#r4:]] "r4"
8+
; CHECK-DAG: OpName %[[#r5:]] "r5"
9+
; CHECK-DAG: OpName %[[#r6:]] "r6"
10+
11+
; CHECK-NOT: OpDecorate %[[#r5]] FPRoundingMode
12+
; CHECK-NOT: OpDecorate %[[#r6]] FPRoundingMode
13+
14+
; CHECK-DAG: OpDecorate %[[#r1]] FPRoundingMode RTE
15+
; CHECK-DAG: OpDecorate %[[#r2]] FPRoundingMode RTZ
16+
; CHECK-DAG: OpDecorate %[[#r4]] FPRoundingMode RTN
17+
; CHECK-DAG: OpDecorate %[[#r3]] FPRoundingMode RTP
18+
19+
; CHECK: OpFAdd %[[#]] %[[#]]
20+
; CHECK: OpFDiv %[[#]] %[[#]]
21+
; CHECK: OpFSub %[[#]] %[[#]]
22+
; CHECK: OpFMul %[[#]] %[[#]]
23+
; CHECK: OpExtInst %[[#]] %[[#]] fma %[[#]] %[[#]] %[[#]]
2524
; CHECK: OpFRem
2625

2726
; Function Attrs: norecurse nounwind strictfp
28-
define dso_local spir_kernel void @test(float %a, i32 %in, i32 %ui) local_unnamed_addr #0 !kernel_arg_addr_space !5 !kernel_arg_access_qual !6 !kernel_arg_type !7 !kernel_arg_base_type !7 !kernel_arg_type_qual !8 !kernel_arg_buffer_location !9 {
27+
define dso_local spir_kernel void @test(float %a, i32 %in, i32 %ui) {
2928
entry:
30-
%add = tail call float @llvm.experimental.constrained.fadd.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #2
31-
%add2 = fadd float %a, %a
32-
; %div = tail call float @llvm.experimental.constrained.fdiv.f32(float %a, float %a, metadata !"round.towardzero", metadata !"fpexcept.strict") #2, !fpmath !10
33-
; %sub = tail call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.upward", metadata !"fpexcept.strict") #2
34-
; %mul = tail call float @llvm.experimental.constrained.fmul.f32(float %a, float %a, metadata !"round.downward", metadata !"fpexcept.strict") #2
35-
; %r1 = tail call float @llvm.experimental.constrained.fma.f32(float %a, float %a, float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") #2
36-
; %r2 = tail call float @llvm.experimental.constrained.frem.f32(float %a, float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") #2
29+
%r1 = tail call float @llvm.experimental.constrained.fadd.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
30+
%r2 = tail call float @llvm.experimental.constrained.fdiv.f32(float %a, float %a, metadata !"round.towardzero", metadata !"fpexcept.strict")
31+
%r3 = tail call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.upward", metadata !"fpexcept.strict")
32+
%r4 = tail call float @llvm.experimental.constrained.fmul.f32(float %a, float %a, metadata !"round.downward", metadata !"fpexcept.strict")
33+
%r5 = tail call float @llvm.experimental.constrained.fma.f32(float %a, float %a, float %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
34+
%r6 = tail call float @llvm.experimental.constrained.frem.f32(float %a, float %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
3735
ret void
3836
}
3937

40-
; Function Attrs: inaccessiblememonly nounwind willreturn
41-
declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) #1
42-
43-
; Function Attrs: inaccessiblememonly nounwind willreturn
44-
declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata) #1
45-
46-
; Function Attrs: inaccessiblememonly nounwind willreturn
47-
declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) #1
48-
49-
; Function Attrs: inaccessiblememonly nounwind willreturn
50-
declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata) #1
51-
52-
; Function Attrs: inaccessiblememonly nounwind willreturn
53-
declare float @llvm.experimental.constrained.fmuladd.f32(float, float, float, metadata, metadata) #1
54-
55-
; Function Attrs: inaccessiblememonly nounwind willreturn
56-
declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata) #1
57-
58-
; Function Attrs: inaccessiblememonly nounwind willreturn
59-
declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata) #1
60-
61-
attributes #0 = { norecurse nounwind strictfp "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="test2.cl" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
62-
attributes #1 = { inaccessiblememonly nounwind willreturn }
63-
attributes #2 = { strictfp }
64-
65-
!llvm.module.flags = !{!0}
66-
!opencl.ocl.version = !{!1}
67-
!opencl.spir.version = !{!2, !2}
68-
!spirv.Source = !{!3}
69-
!llvm.ident = !{!4}
70-
71-
!0 = !{i32 1, !"wchar_size", i32 4}
72-
!1 = !{i32 1, i32 0}
73-
!2 = !{i32 1, i32 2}
74-
!3 = !{i32 4, i32 100000}
75-
!4 = !{!"clang version 12.0.0 (https://github.com/c199914007/llvm.git f0c85a8adeb49638c01eee1451aa9b35462cbfd5)"}
76-
!5 = !{i32 0, i32 0, i32 0}
77-
!6 = !{!"none", !"none", !"none"}
78-
!7 = !{!"float", !"int", !"uint"}
79-
!8 = !{!"", !"", !""}
80-
!9 = !{i32 -1, i32 -1, i32 -1}
81-
!10 = !{float 2.500000e+00}
38+
declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
39+
declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)
40+
declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
41+
declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)
42+
declare float @llvm.experimental.constrained.fmuladd.f32(float, float, float, metadata, metadata)
43+
declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
44+
declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata)

0 commit comments

Comments
 (0)