llvm.org GIT mirror llvm / d1e8486
[AMDGPU][MC] Disabled use of 2 different literals with SOP2/SOPC instructions See bug 39319: https://bugs.llvm.org/show_bug.cgi?id=39319 Reviewers: artem.tamazov, arsenm, rampitec Differential Revision: https://reviews.llvm.org/D56847 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351549 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitry Preobrazhensky 1 year, 9 months ago
6 changed file(s) with 71 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
10831083 OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
10841084
10851085 bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc);
1086 bool validateSOPLiteral(const MCInst &Inst) const;
10861087 bool validateConstantBusLimitations(const MCInst &Inst);
10871088 bool validateEarlyClobberLimitations(const MCInst &Inst);
10881089 bool validateIntClampSupported(const MCInst &Inst);
24602461 return true;
24612462 }
24622463
2464 bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const {
2465 unsigned Opcode = Inst.getOpcode();
2466 const MCInstrDesc &Desc = MII.get(Opcode);
2467 if (!(Desc.TSFlags & (SIInstrFlags::SOP2 | SIInstrFlags::SOPC)))
2468 return true;
2469
2470 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
2471 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
2472
2473 const int OpIndices[] = { Src0Idx, Src1Idx };
2474
2475 unsigned NumLiterals = 0;
2476 uint32_t LiteralValue;
2477
2478 for (int OpIdx : OpIndices) {
2479 if (OpIdx == -1) break;
2480
2481 const MCOperand &MO = Inst.getOperand(OpIdx);
2482 if (MO.isImm() &&
2483 // Exclude special imm operands (like that used by s_set_gpr_idx_on)
2484 AMDGPU::isSISrcOperand(Desc, OpIdx) &&
2485 !isInlineConstant(Inst, OpIdx)) {
2486 uint32_t Value = static_cast(MO.getImm());
2487 if (NumLiterals == 0 || LiteralValue != Value) {
2488 LiteralValue = Value;
2489 ++NumLiterals;
2490 }
2491 }
2492 }
2493
2494 return NumLiterals <= 1;
2495 }
2496
24632497 bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
24642498 const SMLoc &IDLoc) {
2499 if (!validateSOPLiteral(Inst)) {
2500 Error(IDLoc,
2501 "only one literal operand is allowed");
2502 return false;
2503 }
24652504 if (!validateConstantBusLimitations(Inst)) {
24662505 Error(IDLoc,
24672506 "invalid operand (violates constant bus restrictions)");
301301 // copy relevant pseudo op flags
302302 let SubtargetPredicate = ps.SubtargetPredicate;
303303 let AsmMatchConverter = ps.AsmMatchConverter;
304 let UseNamedOperandTable = ps.UseNamedOperandTable;
305 let TSFlags = ps.TSFlags;
304306
305307 // encoding
306308 bits<7> sdst;
44
55 s_cbranch_g_fork s[6:7], 100
66 // GCN: error: invalid operand for instruction
7
8 s_and_b32 s2, 0x12345678, 0x12345679
9 // GCN: error: only one literal operand is allowed
10
11 s_and_b64 s[2:3], 0x12345678, 0x12345679
12 // GCN: error: only one literal operand is allowed
4949 // SICI: s_and_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x87]
5050 // GFX89: s_and_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x86]
5151
52 s_and_b32 s2, 1234, 1234
53 // SICI: s_and_b32 s2, 0x4d2, 0x4d2 ; encoding: [0xff,0xff,0x02,0x87,0xd2,0x04,0x00,0x00]
54 // GFX89: s_and_b32 s2, 0x4d2, 0x4d2 ; encoding: [0xff,0xff,0x02,0x86,0xd2,0x04,0x00,0x00]
55
56 s_and_b32 s2, 0xFFFF0000, -65536
57 // SICI: s_and_b32 s2, 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x02,0x87,0x00,0x00,0xff,0xff]
58 // GFX89: s_and_b32 s2, 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x02,0x86,0x00,0x00,0xff,0xff]
59
5260 s_and_b64 s[2:3], s[4:5], s[6:7]
5361 // SICI: s_and_b64 s[2:3], s[4:5], s[6:7] ; encoding: [0x04,0x06,0x82,0x87]
5462 // GFX89: s_and_b64 s[2:3], s[4:5], s[6:7] ; encoding: [0x04,0x06,0x82,0x86]
133141 // SICI: s_ashr_i64 s[2:3], s[4:5], s6 ; encoding: [0x04,0x06,0x82,0x91]
134142 // GFX89: s_ashr_i64 s[2:3], s[4:5], s6 ; encoding: [0x04,0x06,0x82,0x90]
135143
144 s_ashr_i64 s[2:3], -65536, 0xFFFF0000
145 // SICI: s_ashr_i64 s[2:3], 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x82,0x91,0x00,0x00,0xff,0xff]
146 // GFX89: s_ashr_i64 s[2:3], 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x82,0x90,0x00,0x00,0xff,0xff]
147
136148 s_bfm_b32 s2, s4, s6
137149 // SICI: s_bfm_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x92]
138150 // GFX89: s_bfm_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x91]
77
88 s_set_gpr_idx_on s0, -1
99 // GCN: error: invalid operand for instruction
10
11 s_cmp_eq_i32 0x12345678, 0x12345679
12 // GCN: error: only one literal operand is allowed
13
14 s_cmp_eq_u64 0x12345678, 0x12345679
15 // GCN: error: only one literal operand is allowed
77
88 s_cmp_eq_i32 s1, s2
99 // GCN: s_cmp_eq_i32 s1, s2 ; encoding: [0x01,0x02,0x00,0xbf]
10
11 s_cmp_eq_i32 0xabcd1234, 0xabcd1234
12 // GCN: s_cmp_eq_i32 0xabcd1234, 0xabcd1234 ; encoding: [0xff,0xff,0x00,0xbf,0x34,0x12,0xcd,0xab]
13
14 s_cmp_eq_i32 0xFFFF0000, -65536
15 // GCN: s_cmp_eq_i32 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x00,0xbf,0x00,0x00,0xff,0xff]
1016
1117 s_cmp_lg_i32 s1, s2
1218 // GCN: s_cmp_lg_i32 s1, s2 ; encoding: [0x01,0x02,0x01,0xbf]