From 93c678a79b0a8914954d77973593ea36706db5d5 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 31 Jul 2020 17:07:20 -0700 Subject: [PATCH] [X86] Simplify vpternlog immediate selection. Rather than hardcoding immediate values for 12 different combinations in a nested pair of switches, we can perform the matched logic operation on 3 magic constants to calculate the immediate. Special thanks to this tweet https://twitter.com/rygorous/status/1187034321992871936 for making me realize I could do this. --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 49 ++++++++++++--------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 697c160..3b33349 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -3974,39 +3974,26 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) { SDValue B = FoldableOp.getOperand(0); SDValue C = FoldableOp.getOperand(1); - unsigned Opc1 = N->getOpcode(); - unsigned Opc2 = FoldableOp.getOpcode(); + // We can build the appropriate control immediate by performing the logic + // operation we're matching using these constants for A, B, and C. + const uint8_t TernlogMagicA = 0xf0; + const uint8_t TernlogMagicB = 0xcc; + const uint8_t TernlogMagicC = 0xaa; + + uint8_t Imm; + switch (FoldableOp.getOpcode()) { + default: llvm_unreachable("Unexpected opcode!"); + case ISD::AND: Imm = TernlogMagicB & TernlogMagicC; break; + case ISD::OR: Imm = TernlogMagicB | TernlogMagicC; break; + case ISD::XOR: Imm = TernlogMagicB ^ TernlogMagicC; break; + case X86ISD::ANDNP: Imm = ~(TernlogMagicB) & TernlogMagicC; break; + } - uint64_t Imm; - switch (Opc1) { + switch (N->getOpcode()) { default: llvm_unreachable("Unexpected opcode!"); - case ISD::AND: - switch (Opc2) { - default: llvm_unreachable("Unexpected opcode!"); - case ISD::AND: Imm = 0x80; break; - case ISD::OR: Imm = 0xe0; break; - case ISD::XOR: Imm = 0x60; break; - case X86ISD::ANDNP: Imm = 0x20; break; - } - break; - case ISD::OR: - switch (Opc2) { - default: llvm_unreachable("Unexpected opcode!"); - case ISD::AND: Imm = 0xf8; break; - case ISD::OR: Imm = 0xfe; break; - case ISD::XOR: Imm = 0xf6; break; - case X86ISD::ANDNP: Imm = 0xf2; break; - } - break; - case ISD::XOR: - switch (Opc2) { - default: llvm_unreachable("Unexpected opcode!"); - case ISD::AND: Imm = 0x78; break; - case ISD::OR: Imm = 0x1e; break; - case ISD::XOR: Imm = 0x96; break; - case X86ISD::ANDNP: Imm = 0xd2; break; - } - break; + case ISD::AND: Imm &= TernlogMagicA; break; + case ISD::OR: Imm |= TernlogMagicA; break; + case ISD::XOR: Imm ^= TernlogMagicA; break; } auto tryFoldLoadOrBCast = -- 2.7.4