Skip to content

Commit

Permalink
[X86] Decode VPTERNLOG truth tables when disassembling
Browse files Browse the repository at this point in the history
Alongside something like:
  vpternlogq      zmm0, zmm2, zmm1, 64

We will now have a comment on the right like:
  # zmm0 = zmm0 & zmm2 & ~zmm1

This makes it easy to tell at a glance what sort of truth table the
instruction will provide.
  • Loading branch information
majnemer committed Sep 30, 2024
1 parent 53943de commit 6c5277b
Show file tree
Hide file tree
Showing 17 changed files with 1,370 additions and 1,021 deletions.
92 changes: 92 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86InstComments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ using namespace llvm;
CASE_MASK_INS_COMMON(Inst, Suffix, src) \
CASE_MASKZ_INS_COMMON(Inst, Suffix, src)

#define CASE_PTERNLOG(Inst, src) \
CASE_AVX512_INS_COMMON(Inst, Z, r##src##i) \
CASE_AVX512_INS_COMMON(Inst, Z256, r##src##i) \
CASE_AVX512_INS_COMMON(Inst, Z128, r##src##i)

#define CASE_MOVDUP(Inst, src) \
CASE_AVX512_INS_COMMON(Inst, Z, r##src) \
CASE_AVX512_INS_COMMON(Inst, Z256, r##src) \
Expand Down Expand Up @@ -617,6 +622,90 @@ static bool printFMAComments(const MCInst *MI, raw_ostream &OS,
return true;
}

static bool printPTERNLOGComments(const MCInst *MI, raw_ostream &OS,
const MCInstrInfo &MCII) {
unsigned NumOperands = MI->getNumOperands();

int Src2Idx;
int Src3Idx;
switch (MI->getOpcode()) {
// dest, src1, src2, src3, tbl
// dest, src1, mask, src2, src3, tbl
CASE_PTERNLOG(PTERNLOGD, r)
CASE_PTERNLOG(PTERNLOGQ, r)
Src2Idx = NumOperands - 3;
Src3Idx = NumOperands - 2;
break;

// dest, src1, src2, memory, tbl
// dest, src1, mask, src2, memory, tbl
CASE_PTERNLOG(PTERNLOGD, m)
CASE_PTERNLOG(PTERNLOGQ, m)
CASE_PTERNLOG(PTERNLOGD, mb)
CASE_PTERNLOG(PTERNLOGQ, mb)
Src2Idx = NumOperands - 7;
Src3Idx = -1;
break;

default:
return false;
}
const char *DestName = getRegName(MI->getOperand(0).getReg());
const char *Src1Name = getRegName(MI->getOperand(1).getReg());
const char *Src2Name = getRegName(MI->getOperand(Src2Idx).getReg());
const char *Src3Name =
Src3Idx != -1 ? getRegName(MI->getOperand(Src3Idx).getReg()) : "mem";
uint8_t TruthTable = MI->getOperand(NumOperands - 1).getImm();

OS << DestName;
printMasking(OS, MI, MCII);
OS << " = ";

constexpr unsigned kNumVariables = 3;
constexpr unsigned kNumTruthTableEntries = 1 << kNumVariables;
int NumMinterms = llvm::popcount(TruthTable);
if (NumMinterms == 0) {
OS << '0';
} else if (NumMinterms == kNumTruthTableEntries) {
OS << "-1";
} else {
while (TruthTable != 0) {
// Index of the lowest bit set.
unsigned I = llvm::countr_zero(TruthTable);
// Clear the lowest bit set.
TruthTable &= TruthTable - 1;
// Our index tells us which sources are and are not complemented. Note
// that the indexing goes left-to-right.
bool Src1 = I & 0b100;
bool Src2 = I & 0b010;
bool Src3 = I & 0b001;

// Group in parenthesis to make the output more obvious but only if there
// are multiple terms.
if (NumMinterms > 1)
OS << '(';

if (!Src1)
OS << '~';
OS << Src1Name << " & ";
if (!Src2)
OS << '~';
OS << Src2Name << " & ";
if (!Src3)
OS << '~';
OS << Src3Name;

if (NumMinterms > 1)
OS << ')';

// Output an OR if there is another term in the table.
if (TruthTable != 0)
OS << " | ";
}
}
OS << '\n';
return true;
}

//===----------------------------------------------------------------------===//
// Top Level Entrypoint
Expand All @@ -636,6 +725,9 @@ bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
if (printFMAComments(MI, OS, MCII))
return true;

if (printPTERNLOGComments(MI, OS, MCII))
return true;

switch (MI->getOpcode()) {
default:
// Not an instruction for which we can decode comments.
Expand Down
74 changes: 74 additions & 0 deletions llvm/test/CodeGen/X86/avx512-gfni-intrinsics.ll

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions llvm/test/CodeGen/X86/avx512-intrinsics-upgrade.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7682,6 +7682,7 @@ define <16 x i32>@test_int_x86_avx512_pternlog_d_512(<16 x i32> %x0, <16 x i32>
; CHECK-LABEL: test_int_x86_avx512_pternlog_d_512:
; CHECK: ## %bb.0:
; CHECK-NEXT: vpternlogd $33, %zmm2, %zmm1, %zmm0 ## encoding: [0x62,0xf3,0x75,0x48,0x25,0xc2,0x21]
; CHECK-NEXT: ## zmm0 = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; CHECK-NEXT: ret{{[l|q]}} ## encoding: [0xc3]
%res = call <16 x i32> @llvm.x86.avx512.mask.pternlog.d.512(<16 x i32> %x0, <16 x i32> %x1, <16 x i32> %x2, i32 33, i16 -1)
ret <16 x i32> %res
Expand All @@ -7692,12 +7693,14 @@ define <16 x i32>@test_int_x86_avx512_mask_pternlog_d_512(<16 x i32> %x0, <16 x
; X86: ## %bb.0:
; X86-NEXT: kmovw {{[0-9]+}}(%esp), %k1 ## encoding: [0xc5,0xf8,0x90,0x4c,0x24,0x04]
; X86-NEXT: vpternlogd $33, %zmm2, %zmm1, %zmm0 {%k1} ## encoding: [0x62,0xf3,0x75,0x49,0x25,0xc2,0x21]
; X86-NEXT: ## zmm0 {%k1} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X86-NEXT: retl ## encoding: [0xc3]
;
; X64-LABEL: test_int_x86_avx512_mask_pternlog_d_512:
; X64: ## %bb.0:
; X64-NEXT: kmovw %edi, %k1 ## encoding: [0xc5,0xf8,0x92,0xcf]
; X64-NEXT: vpternlogd $33, %zmm2, %zmm1, %zmm0 {%k1} ## encoding: [0x62,0xf3,0x75,0x49,0x25,0xc2,0x21]
; X64-NEXT: ## zmm0 {%k1} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X64-NEXT: retq ## encoding: [0xc3]
%res = call <16 x i32> @llvm.x86.avx512.mask.pternlog.d.512(<16 x i32> %x0, <16 x i32> %x1, <16 x i32> %x2, i32 33, i16 %x4)
ret <16 x i32> %res
Expand All @@ -7710,12 +7713,14 @@ define <16 x i32>@test_int_x86_avx512_maskz_pternlog_d_512(<16 x i32> %x0, <16 x
; X86: ## %bb.0:
; X86-NEXT: kmovw {{[0-9]+}}(%esp), %k1 ## encoding: [0xc5,0xf8,0x90,0x4c,0x24,0x04]
; X86-NEXT: vpternlogd $33, %zmm2, %zmm1, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x75,0xc9,0x25,0xc2,0x21]
; X86-NEXT: ## zmm0 {%k1} {z} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X86-NEXT: retl ## encoding: [0xc3]
;
; X64-LABEL: test_int_x86_avx512_maskz_pternlog_d_512:
; X64: ## %bb.0:
; X64-NEXT: kmovw %edi, %k1 ## encoding: [0xc5,0xf8,0x92,0xcf]
; X64-NEXT: vpternlogd $33, %zmm2, %zmm1, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x75,0xc9,0x25,0xc2,0x21]
; X64-NEXT: ## zmm0 {%k1} {z} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X64-NEXT: retq ## encoding: [0xc3]
%res = call <16 x i32> @llvm.x86.avx512.maskz.pternlog.d.512(<16 x i32> %x0, <16 x i32> %x1, <16 x i32> %x2, i32 33, i16 %x4)
ret <16 x i32> %res
Expand All @@ -7727,6 +7732,7 @@ define <8 x i64>@test_int_x86_avx512_pternlog_q_512(<8 x i64> %x0, <8 x i64> %x1
; CHECK-LABEL: test_int_x86_avx512_pternlog_q_512:
; CHECK: ## %bb.0:
; CHECK-NEXT: vpternlogq $33, %zmm2, %zmm1, %zmm0 ## encoding: [0x62,0xf3,0xf5,0x48,0x25,0xc2,0x21]
; CHECK-NEXT: ## zmm0 = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; CHECK-NEXT: ret{{[l|q]}} ## encoding: [0xc3]
%res = call <8 x i64> @llvm.x86.avx512.mask.pternlog.q.512(<8 x i64> %x0, <8 x i64> %x1, <8 x i64> %x2, i32 33, i8 -1)
ret <8 x i64> %res
Expand All @@ -7738,12 +7744,14 @@ define <8 x i64>@test_int_x86_avx512_mask_pternlog_q_512(<8 x i64> %x0, <8 x i64
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax ## encoding: [0x0f,0xb6,0x44,0x24,0x04]
; X86-NEXT: kmovw %eax, %k1 ## encoding: [0xc5,0xf8,0x92,0xc8]
; X86-NEXT: vpternlogq $33, %zmm2, %zmm1, %zmm0 {%k1} ## encoding: [0x62,0xf3,0xf5,0x49,0x25,0xc2,0x21]
; X86-NEXT: ## zmm0 {%k1} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X86-NEXT: retl ## encoding: [0xc3]
;
; X64-LABEL: test_int_x86_avx512_mask_pternlog_q_512:
; X64: ## %bb.0:
; X64-NEXT: kmovw %edi, %k1 ## encoding: [0xc5,0xf8,0x92,0xcf]
; X64-NEXT: vpternlogq $33, %zmm2, %zmm1, %zmm0 {%k1} ## encoding: [0x62,0xf3,0xf5,0x49,0x25,0xc2,0x21]
; X64-NEXT: ## zmm0 {%k1} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X64-NEXT: retq ## encoding: [0xc3]
%res = call <8 x i64> @llvm.x86.avx512.mask.pternlog.q.512(<8 x i64> %x0, <8 x i64> %x1, <8 x i64> %x2, i32 33, i8 %x4)
ret <8 x i64> %res
Expand All @@ -7757,12 +7765,14 @@ define <8 x i64>@test_int_x86_avx512_maskz_pternlog_q_512(<8 x i64> %x0, <8 x i6
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax ## encoding: [0x0f,0xb6,0x44,0x24,0x04]
; X86-NEXT: kmovw %eax, %k1 ## encoding: [0xc5,0xf8,0x92,0xc8]
; X86-NEXT: vpternlogq $33, %zmm2, %zmm1, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0xf5,0xc9,0x25,0xc2,0x21]
; X86-NEXT: ## zmm0 {%k1} {z} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X86-NEXT: retl ## encoding: [0xc3]
;
; X64-LABEL: test_int_x86_avx512_maskz_pternlog_q_512:
; X64: ## %bb.0:
; X64-NEXT: kmovw %edi, %k1 ## encoding: [0xc5,0xf8,0x92,0xcf]
; X64-NEXT: vpternlogq $33, %zmm2, %zmm1, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0xf5,0xc9,0x25,0xc2,0x21]
; X64-NEXT: ## zmm0 {%k1} {z} = (~zmm0 & ~zmm1 & ~zmm2) | (zmm0 & ~zmm1 & zmm2)
; X64-NEXT: retq ## encoding: [0xc3]
%res = call <8 x i64> @llvm.x86.avx512.maskz.pternlog.q.512(<8 x i64> %x0, <8 x i64> %x1, <8 x i64> %x2, i32 33, i8 %x4)
ret <8 x i64> %res
Expand Down
7 changes: 7 additions & 0 deletions llvm/test/CodeGen/X86/avx512-vec-cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ define <16 x i32> @test13(<16 x float>%a, <16 x float>%b)
; AVX512: ## %bb.0:
; AVX512-NEXT: vcmpeqps %zmm1, %zmm0, %k1 ## encoding: [0x62,0xf1,0x7c,0x48,0xc2,0xc9,0x00]
; AVX512-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; AVX512-NEXT: ## zmm0 {%k1} {z} = -1
; AVX512-NEXT: vpsrld $31, %zmm0, %zmm0 ## encoding: [0x62,0xf1,0x7d,0x48,0x72,0xd0,0x1f]
; AVX512-NEXT: retq ## encoding: [0xc3]
;
Expand Down Expand Up @@ -520,6 +521,7 @@ define <8 x i32>@test28(<8 x i64> %x, <8 x i64> %y, <8 x i64> %x1, <8 x i64> %y1
; AVX512-NEXT: vpcmpgtq %zmm3, %zmm2, %k1 ## encoding: [0x62,0xf2,0xed,0x48,0x37,0xcb]
; AVX512-NEXT: kxnorw %k1, %k0, %k1 ## encoding: [0xc5,0xfc,0x46,0xc9]
; AVX512-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; AVX512-NEXT: ## zmm0 {%k1} {z} = -1
; AVX512-NEXT: ## kill: def $ymm0 killed $ymm0 killed $zmm0
; AVX512-NEXT: retq ## encoding: [0xc3]
;
Expand All @@ -544,6 +546,7 @@ define <16 x i8>@test29(<16 x i32> %x, <16 x i32> %y, <16 x i32> %x1, <16 x i32>
; KNL-NEXT: vpcmpgtd %zmm3, %zmm2, %k1 ## encoding: [0x62,0xf1,0x6d,0x48,0x66,0xcb]
; KNL-NEXT: kxorw %k1, %k0, %k1 ## encoding: [0xc5,0xfc,0x47,0xc9]
; KNL-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; KNL-NEXT: ## zmm0 {%k1} {z} = -1
; KNL-NEXT: vpmovdb %zmm0, %xmm0 ## encoding: [0x62,0xf2,0x7e,0x48,0x31,0xc0]
; KNL-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77]
; KNL-NEXT: retq ## encoding: [0xc3]
Expand Down Expand Up @@ -1233,6 +1236,7 @@ define <16 x i8> @test47(<16 x i32> %a, <16 x i8> %b, <16 x i8> %c) {
; KNL: ## %bb.0:
; KNL-NEXT: vptestnmd %zmm0, %zmm0, %k1 ## encoding: [0x62,0xf2,0x7e,0x48,0x27,0xc8]
; KNL-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; KNL-NEXT: ## zmm0 {%k1} {z} = -1
; KNL-NEXT: vpmovdb %zmm0, %xmm0 ## encoding: [0x62,0xf2,0x7e,0x48,0x31,0xc0]
; KNL-NEXT: vpblendvb %xmm0, %xmm1, %xmm2, %xmm0 ## encoding: [0xc4,0xe3,0x69,0x4c,0xc1,0x00]
; KNL-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77]
Expand Down Expand Up @@ -1264,6 +1268,7 @@ define <16 x i16> @test48(<16 x i32> %a, <16 x i16> %b, <16 x i16> %c) {
; KNL: ## %bb.0:
; KNL-NEXT: vptestnmd %zmm0, %zmm0, %k1 ## encoding: [0x62,0xf2,0x7e,0x48,0x27,0xc8]
; KNL-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; KNL-NEXT: ## zmm0 {%k1} {z} = -1
; KNL-NEXT: vpmovdw %zmm0, %ymm0 ## encoding: [0x62,0xf2,0x7e,0x48,0x33,0xc0]
; KNL-NEXT: vpblendvb %ymm0, %ymm1, %ymm2, %ymm0 ## encoding: [0xc4,0xe3,0x6d,0x4c,0xc1,0x00]
; KNL-NEXT: retq ## encoding: [0xc3]
Expand Down Expand Up @@ -1292,6 +1297,7 @@ define <8 x i16> @test49(<8 x i64> %a, <8 x i16> %b, <8 x i16> %c) {
; KNL: ## %bb.0:
; KNL-NEXT: vptestnmq %zmm0, %zmm0, %k1 ## encoding: [0x62,0xf2,0xfe,0x48,0x27,0xc8]
; KNL-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; KNL-NEXT: ## zmm0 {%k1} {z} = -1
; KNL-NEXT: vpmovdw %zmm0, %ymm0 ## encoding: [0x62,0xf2,0x7e,0x48,0x33,0xc0]
; KNL-NEXT: vpblendvb %xmm0, %xmm1, %xmm2, %xmm0 ## encoding: [0xc4,0xe3,0x69,0x4c,0xc1,0x00]
; KNL-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77]
Expand Down Expand Up @@ -1408,6 +1414,7 @@ define <4 x i32> @zext_bool_logic(<4 x i64> %cond1, <4 x i64> %cond2, <4 x i32>
; AVX512-NEXT: vptestnmq %zmm1, %zmm1, %k1 ## encoding: [0x62,0xf2,0xf6,0x48,0x27,0xc9]
; AVX512-NEXT: korw %k1, %k0, %k1 ## encoding: [0xc5,0xfc,0x45,0xc9]
; AVX512-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ## encoding: [0x62,0xf3,0x7d,0xc9,0x25,0xc0,0xff]
; AVX512-NEXT: ## zmm0 {%k1} {z} = -1
; AVX512-NEXT: vpsubd %xmm0, %xmm2, %xmm0 ## encoding: [0xc5,0xe9,0xfa,0xc0]
; AVX512-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77]
; AVX512-NEXT: retq ## encoding: [0xc3]
Expand Down
Loading

0 comments on commit 6c5277b

Please sign in to comment.