Skip to content

Commit 46db606

Browse files
committed
AMDGPU: Avoid folding 2 constant operands into an SALU operation
Summary: Catch the (admittedly unusual) case where SIFoldOperands attempts to fold 2 constant operands into the same SALU operation, with neither operand able to be encoded as an inline constant. Change-Id: Ibc48d662c9ffd8bbacd154976b0b1c257ace0927 Subscribers: arsenm, kzhuravl, jvesely, wdng, nhaehnle, yaxunl, tpr, t-tye, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70896
1 parent daff7b8 commit 46db606

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

llvm/lib/Target/AMDGPU/SIFoldOperands.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,29 @@ static bool tryAddToFoldList(SmallVectorImpl<FoldCandidate> &FoldList,
429429
return true;
430430
}
431431

432+
// Check the case where we might introduce a second constant operand to a
433+
// scalar instruction
434+
if (TII->isSALU(MI->getOpcode())) {
435+
const MCInstrDesc &InstDesc = MI->getDesc();
436+
const MCOperandInfo &OpInfo = InstDesc.OpInfo[OpNo];
437+
const SIRegisterInfo &SRI = TII->getRegisterInfo();
438+
439+
// Fine if the operand can be encoded as an inline constant
440+
if (OpToFold->isImm()) {
441+
if (!SRI.opCanUseInlineConstant(OpInfo.OperandType) ||
442+
!TII->isInlineConstant(*OpToFold, OpInfo)) {
443+
// Otherwise check for another constant
444+
for (unsigned i = 0, e = InstDesc.getNumOperands(); i != e; ++i) {
445+
auto &Op = MI->getOperand(i);
446+
if (OpNo != i &&
447+
TII->isLiteralConstantLike(Op, OpInfo)) {
448+
return false;
449+
}
450+
}
451+
}
452+
}
453+
}
454+
432455
appendFoldCandidate(FoldList, MI, OpNo, OpToFold);
433456
return true;
434457
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# RUN: llc -march=amdgcn -verify-machineinstrs -run-pass si-fold-operands %s -o - | FileCheck -check-prefix=GCN %s
2+
3+
# GCN-LABEL: name: test_part_fold{{$}}
4+
# GCN: %2:sreg_32 = S_ADD_I32 70, %1
5+
---
6+
name: test_part_fold
7+
tracksRegLiveness: true
8+
body: |
9+
bb.0:
10+
%0:sreg_32 = S_MOV_B32 70
11+
%1:sreg_32 = S_MOV_B32 80
12+
%2:sreg_32 = S_ADD_I32 %0, %1, implicit-def $scc
13+
...
14+
15+
# GCN-LABEL: name: test_inline_const{{$}}
16+
# GCN: %2:sreg_32 = S_ADD_I32 70, 63
17+
---
18+
name: test_inline_const
19+
tracksRegLiveness: true
20+
body: |
21+
bb.0:
22+
%0:sreg_32 = S_MOV_B32 70
23+
%1:sreg_32 = S_MOV_B32 63
24+
%2:sreg_32 = S_ADD_I32 %0, %1, implicit-def $scc
25+
...
26+
# GCN-LABEL: name: test_obscure{{$}}
27+
# GCN: %2:sreg_32 = S_LSHL2_ADD_U32 70, %1
28+
---
29+
name: test_obscure
30+
tracksRegLiveness: true
31+
body: |
32+
bb.0:
33+
%0:sreg_32 = S_MOV_B32 70
34+
%1:sreg_32 = S_MOV_B32 80
35+
%2:sreg_32 = S_LSHL2_ADD_U32 %0, %1, implicit-def $scc
36+
...
37+
# GCN-LABEL: name: test_obscure_inline{{$}}
38+
# GCN: %2:sreg_32 = S_LSHL2_ADD_U32 70, 63
39+
---
40+
name: test_obscure_inline
41+
tracksRegLiveness: true
42+
body: |
43+
bb.0:
44+
%0:sreg_32 = S_MOV_B32 70
45+
%1:sreg_32 = S_MOV_B32 63
46+
%2:sreg_32 = S_LSHL2_ADD_U32 %0, %1, implicit-def $scc
47+
...
48+
# GCN-LABEL: name: test_frameindex{{$}}
49+
# GCN: %1:sreg_32 = S_ADD_I32 %stack.0, %0
50+
---
51+
name: test_frameindex
52+
tracksRegLiveness: true
53+
stack:
54+
- { id: 0, type: default, offset: 0, size: 64, alignment: 16}
55+
body: |
56+
bb.0:
57+
%0:sreg_32 = S_MOV_B32 70
58+
%1:sreg_32 = S_ADD_I32 %stack.0, %0, implicit-def $scc
59+
...
60+
# GCN-LABEL: name: test_frameindex_inline{{$}}
61+
# GCN: %1:sreg_32 = S_ADD_I32 %stack.0, 63
62+
---
63+
name: test_frameindex_inline
64+
tracksRegLiveness: true
65+
stack:
66+
- { id: 0, type: default, offset: 0, size: 64, alignment: 16}
67+
body: |
68+
bb.0:
69+
%0:sreg_32 = S_MOV_B32 63
70+
%1:sreg_32 = S_ADD_I32 %stack.0, %0, implicit-def $scc
71+
...

0 commit comments

Comments
 (0)