-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[GISel][AArch64] Allow PatLeafs to be imported in GISel which were previously causing warnings #140935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-backend-aarch64 Author: None (jyli0116) ChangesPreviously PatLeafs could not be imported, causing the following warnings to be emitted when running tblgen with
These changes allow the patterns to now be imported successfully. Patch is 52.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140935.diff 19 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 6a7c0edbf2ce0..0b904915b9614 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -160,6 +160,12 @@ enum {
/// - Pred(2) - The predicate to test
GIM_CheckImmOperandPredicate,
+ /// Check a register predicate on the specified instruction.
+ /// - InsnID(ULEB128) - Instruction ID
+ /// - OpIdx(ULEB128) - Operand index
+ /// - Pred(2) - The predicate to test
+ GIM_CheckRegOperandPredicate,
+
/// Check a memory operation has the specified atomic ordering.
/// - InsnID(ULEB128) - Instruction ID
/// - Ordering(ULEB128) - The AtomicOrdering value
@@ -706,6 +712,12 @@ class GIMatchTableExecutor {
"Subclasses must override this with a tablegen-erated function");
}
+ virtual bool testMOPredicate_MO(unsigned, const MachineOperand &,
+ const MatcherState &State) const {
+ llvm_unreachable(
+ "Subclasses must override this with a tablegen-erated function");
+ }
+
virtual bool testSimplePredicate(unsigned) const {
llvm_unreachable("Subclass does not implement testSimplePredicate!");
}
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 6c4f03649149e..58d64671307d4 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -410,6 +410,26 @@ bool GIMatchTableExecutor::executeMatchTable(
return false;
break;
}
+ case GIM_CheckRegOperandPredicate: {
+ uint64_t InsnID = readULEB();
+ uint64_t OpIdx = readULEB();
+ uint16_t Predicate = readU16();
+ DEBUG_WITH_TYPE(TgtExecutor::getName(),
+ dbgs()
+ << CurrentIdx << ": GIM_CheckRegOperandPredicate(MIs["
+ << InsnID << "]->getOperand(" << OpIdx
+ << "), Predicate=" << Predicate << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ assert(State.MIs[InsnID]->getOperand(OpIdx).isReg() &&
+ "Expected register operand");
+ assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
+ MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
+
+ if (!testMOPredicate_MO(Predicate, MO, State))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
case GIM_CheckIsBuildVectorAllOnes:
case GIM_CheckIsBuildVectorAllZeros: {
uint64_t InsnID = readULEB();
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 406baa4f5fdaa..933132d62866f 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -959,6 +959,7 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
list<dag> Fragments = frags;
code PredicateCode = pred;
code GISelPredicateCode = [{}];
+ code GISelRegPredicateCode = [{}];
code ImmediateCode = [{}];
SDNodeXForm OperandTransform = xform;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 22ecf99b12de6..2aadc4ae062e1 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -685,23 +685,31 @@ defm trunc_masked_scatter_i32 : masked_gather_scatter<trunc_masked_scatter_i32>;
def top16Zero: PatLeaf<(i32 GPR32:$src), [{
return Op.getValueType() == MVT::i32 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(32, 16));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{return isTop16Zero(MO); }];
+}
// top32Zero - answer true if the upper 32 bits of $src are 0, false otherwise
def top32Zero: PatLeaf<(i64 GPR64:$src), [{
return Op.getValueType() == MVT::i64 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(64, 32));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTop32Zero(MO); }];
+}
// topbitsallzero - Return true if all bits except the lowest bit are known zero
def topbitsallzero32: PatLeaf<(i32 GPR32:$src), [{
return Op.getValueType() == MVT::i32 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(32, 31));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTopBitsAllZero32(MO); }];
+}
def topbitsallzero64: PatLeaf<(i64 GPR64:$src), [{
return Op.getValueType() == MVT::i64 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(64, 63));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTopBitsAllZero64(MO); }];
+}
// Node definitions.
def AArch64CB : SDNode<"AArch64ISD::CB", SDT_AArch64cb, [SDNPHasChain]>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index e0c693bff3c0a..e1e2c533a9f3b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -22,6 +22,7 @@
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
@@ -510,6 +511,16 @@ class AArch64InstructionSelector : public InstructionSelector {
/// Return true if \p MI is a load or store of \p NumBytes bytes.
bool isLoadStoreOfNumBytes(const MachineInstr &MI, unsigned NumBytes) const;
+ /// Return true if top 16 bits of register are zero.
+ bool isTop16Zero(const MachineOperand &MO) const;
+
+ /// Return true if top 32 bits of register are zero.
+ bool isTop32Zero(const MachineOperand &MO) const;
+
+ /// Return true if all bits of register except the lowest bit are known zero.
+ bool isTopBitsAllZero32(const MachineOperand &MO) const;
+ bool isTopBitsAllZero64(const MachineOperand &MO) const;
+
/// Returns true if \p MI is guaranteed to have the high-half of a 64-bit
/// register zeroed out. In other words, the result of MI has been explicitly
/// zero extended.
@@ -7985,6 +7996,29 @@ bool AArch64InstructionSelector::isLoadStoreOfNumBytes(
return (*MI.memoperands_begin())->getSize() == NumBytes;
}
+bool AArch64InstructionSelector::isTop16Zero(const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(32, 16));
+}
+
+// bool isTop32Zero(const MachineOperand &MO) const;
+bool AArch64InstructionSelector::isTop32Zero(const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(64, 32));
+}
+
+bool AArch64InstructionSelector::isTopBitsAllZero32(
+ const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(32, 31));
+}
+
+bool AArch64InstructionSelector::isTopBitsAllZero64(
+ const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(64, 63));
+}
+
bool AArch64InstructionSelector::isDef32(const MachineInstr &MI) const {
const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
if (MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() != 32)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll b/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
index 8de1fc5762c15..bf73aeb855c09 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
@@ -1291,21 +1291,13 @@ entry:
}
define i64 @umull_ldrb_h(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umull_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1315,21 +1307,13 @@ entry:
}
define i64 @umull_ldrb_h_commuted(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umull_ldrb_h_commuted:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umull x0, w9, w8
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrb_h_commuted:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mul x0, x9, x8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrb_h_commuted:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umull x0, w9, w8
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1339,18 +1323,11 @@ entry:
}
define i64 @umull_ldrh_w(ptr %x0, i32 %x1) {
-; CHECK-SD-LABEL: umull_ldrh_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrh w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrh_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrh w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrh_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrh w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i16, ptr %x0
%zext = zext i16 %ext64 to i64
@@ -1360,21 +1337,13 @@ entry:
}
define i64 @umull_ldr_b(ptr %x0, i8 %x1) {
-; CHECK-SD-LABEL: umull_ldr_b:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xff
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr_b:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xff
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr_b:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xff
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i32, ptr %x0
%zext = zext i32 %ext64 to i64
@@ -1384,18 +1353,11 @@ entry:
}
define i64 @umull_ldr2_w(ptr %x0, i32 %x1) {
-; CHECK-SD-LABEL: umull_ldr2_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1405,19 +1367,12 @@ entry:
}
define i64 @umull_ldr2_ldr2(ptr %x0, ptr %x1) {
-; CHECK-SD-LABEL: umull_ldr2_ldr2:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: ldr w9, [x1]
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_ldr2:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: ldr w9, [x1]
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_ldr2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: ldr w9, [x1]
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1428,18 +1383,11 @@ entry:
}
define i64 @umull_ldr2_d(ptr %x0, i64 %x1) {
-; CHECK-SD-LABEL: umull_ldr2_d:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_d:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_d:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1449,21 +1397,13 @@ entry:
}
define i64 @umaddl_ldrb_h(ptr %x0, i16 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1474,21 +1414,13 @@ entry:
}
define i64 @umaddl_ldrb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrb_h_commuted:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umaddl x0, w9, w8, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrb_h_commuted:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: madd x0, x9, x8, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrb_h_commuted:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umaddl x0, w9, w8, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1499,18 +1431,11 @@ entry:
}
define i64 @umaddl_ldrh_w(ptr %x0, i32 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrh_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrh w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrh_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrh w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrh_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrh w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i16, ptr %x0
%zext = zext i16 %ext64 to i64
@@ -1521,21 +1446,13 @@ entry:
}
define i64 @umaddl_ldr_b(ptr %x0, i8 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr_b:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xff
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr_b:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xff
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr_b:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xff
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i32, ptr %x0
%zext = zext i32 %ext64 to i64
@@ -1546,18 +1463,11 @@ entry:
}
define i64 @umaddl_ldr2_w(ptr %x0, i32 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1568,19 +1478,12 @@ entry:
}
define i64 @umaddl_ldr2_ldr2(ptr %x0, ptr %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_ldr2:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: ldr w9, [x1]
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_ldr2:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: ldr w9, [x1]
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_ldr2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: ldr w9, [x1]
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1592,18 +1495,11 @@ entry:
}
define i64 @umaddl_ldr2_d(ptr %x0, i64 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_d:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_d:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_d:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1614,21 +1510,13 @@ entry:
}
define i64 @umnegl_ldrb_h(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umnegl_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umnegl x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umnegl_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mneg x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umnegl_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umnegl x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1639,21 +1527,13 @@ entry:
}
define i64 @umnegl_ldrb_h_commuted(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umnegl_ldrb_h...
[truncated]
|
@llvm/pr-subscribers-tablegen Author: None (jyli0116) ChangesPreviously PatLeafs could not be imported, causing the following warnings to be emitted when running tblgen with
These changes allow the patterns to now be imported successfully. Patch is 52.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140935.diff 19 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 6a7c0edbf2ce0..0b904915b9614 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -160,6 +160,12 @@ enum {
/// - Pred(2) - The predicate to test
GIM_CheckImmOperandPredicate,
+ /// Check a register predicate on the specified instruction.
+ /// - InsnID(ULEB128) - Instruction ID
+ /// - OpIdx(ULEB128) - Operand index
+ /// - Pred(2) - The predicate to test
+ GIM_CheckRegOperandPredicate,
+
/// Check a memory operation has the specified atomic ordering.
/// - InsnID(ULEB128) - Instruction ID
/// - Ordering(ULEB128) - The AtomicOrdering value
@@ -706,6 +712,12 @@ class GIMatchTableExecutor {
"Subclasses must override this with a tablegen-erated function");
}
+ virtual bool testMOPredicate_MO(unsigned, const MachineOperand &,
+ const MatcherState &State) const {
+ llvm_unreachable(
+ "Subclasses must override this with a tablegen-erated function");
+ }
+
virtual bool testSimplePredicate(unsigned) const {
llvm_unreachable("Subclass does not implement testSimplePredicate!");
}
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 6c4f03649149e..58d64671307d4 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -410,6 +410,26 @@ bool GIMatchTableExecutor::executeMatchTable(
return false;
break;
}
+ case GIM_CheckRegOperandPredicate: {
+ uint64_t InsnID = readULEB();
+ uint64_t OpIdx = readULEB();
+ uint16_t Predicate = readU16();
+ DEBUG_WITH_TYPE(TgtExecutor::getName(),
+ dbgs()
+ << CurrentIdx << ": GIM_CheckRegOperandPredicate(MIs["
+ << InsnID << "]->getOperand(" << OpIdx
+ << "), Predicate=" << Predicate << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ assert(State.MIs[InsnID]->getOperand(OpIdx).isReg() &&
+ "Expected register operand");
+ assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
+ MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
+
+ if (!testMOPredicate_MO(Predicate, MO, State))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
case GIM_CheckIsBuildVectorAllOnes:
case GIM_CheckIsBuildVectorAllZeros: {
uint64_t InsnID = readULEB();
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 406baa4f5fdaa..933132d62866f 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -959,6 +959,7 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
list<dag> Fragments = frags;
code PredicateCode = pred;
code GISelPredicateCode = [{}];
+ code GISelRegPredicateCode = [{}];
code ImmediateCode = [{}];
SDNodeXForm OperandTransform = xform;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 22ecf99b12de6..2aadc4ae062e1 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -685,23 +685,31 @@ defm trunc_masked_scatter_i32 : masked_gather_scatter<trunc_masked_scatter_i32>;
def top16Zero: PatLeaf<(i32 GPR32:$src), [{
return Op.getValueType() == MVT::i32 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(32, 16));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{return isTop16Zero(MO); }];
+}
// top32Zero - answer true if the upper 32 bits of $src are 0, false otherwise
def top32Zero: PatLeaf<(i64 GPR64:$src), [{
return Op.getValueType() == MVT::i64 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(64, 32));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTop32Zero(MO); }];
+}
// topbitsallzero - Return true if all bits except the lowest bit are known zero
def topbitsallzero32: PatLeaf<(i32 GPR32:$src), [{
return Op.getValueType() == MVT::i32 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(32, 31));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTopBitsAllZero32(MO); }];
+}
def topbitsallzero64: PatLeaf<(i64 GPR64:$src), [{
return Op.getValueType() == MVT::i64 &&
CurDAG->MaskedValueIsZero(Op, APInt::getHighBitsSet(64, 63));
- }]>;
+ }]> {
+ let GISelRegPredicateCode = [{ return isTopBitsAllZero64(MO); }];
+}
// Node definitions.
def AArch64CB : SDNode<"AArch64ISD::CB", SDT_AArch64cb, [SDNPHasChain]>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index e0c693bff3c0a..e1e2c533a9f3b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -22,6 +22,7 @@
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
@@ -510,6 +511,16 @@ class AArch64InstructionSelector : public InstructionSelector {
/// Return true if \p MI is a load or store of \p NumBytes bytes.
bool isLoadStoreOfNumBytes(const MachineInstr &MI, unsigned NumBytes) const;
+ /// Return true if top 16 bits of register are zero.
+ bool isTop16Zero(const MachineOperand &MO) const;
+
+ /// Return true if top 32 bits of register are zero.
+ bool isTop32Zero(const MachineOperand &MO) const;
+
+ /// Return true if all bits of register except the lowest bit are known zero.
+ bool isTopBitsAllZero32(const MachineOperand &MO) const;
+ bool isTopBitsAllZero64(const MachineOperand &MO) const;
+
/// Returns true if \p MI is guaranteed to have the high-half of a 64-bit
/// register zeroed out. In other words, the result of MI has been explicitly
/// zero extended.
@@ -7985,6 +7996,29 @@ bool AArch64InstructionSelector::isLoadStoreOfNumBytes(
return (*MI.memoperands_begin())->getSize() == NumBytes;
}
+bool AArch64InstructionSelector::isTop16Zero(const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(32, 16));
+}
+
+// bool isTop32Zero(const MachineOperand &MO) const;
+bool AArch64InstructionSelector::isTop32Zero(const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(64, 32));
+}
+
+bool AArch64InstructionSelector::isTopBitsAllZero32(
+ const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(32, 31));
+}
+
+bool AArch64InstructionSelector::isTopBitsAllZero64(
+ const MachineOperand &MO) const {
+ Register Reg = MO.getReg();
+ return VT->maskedValueIsZero(Reg, APInt::getHighBitsSet(64, 63));
+}
+
bool AArch64InstructionSelector::isDef32(const MachineInstr &MI) const {
const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
if (MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() != 32)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll b/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
index 8de1fc5762c15..bf73aeb855c09 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-mull-masks.ll
@@ -1291,21 +1291,13 @@ entry:
}
define i64 @umull_ldrb_h(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umull_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1315,21 +1307,13 @@ entry:
}
define i64 @umull_ldrb_h_commuted(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umull_ldrb_h_commuted:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umull x0, w9, w8
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrb_h_commuted:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mul x0, x9, x8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrb_h_commuted:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umull x0, w9, w8
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1339,18 +1323,11 @@ entry:
}
define i64 @umull_ldrh_w(ptr %x0, i32 %x1) {
-; CHECK-SD-LABEL: umull_ldrh_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrh w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldrh_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrh w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldrh_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrh w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i16, ptr %x0
%zext = zext i16 %ext64 to i64
@@ -1360,21 +1337,13 @@ entry:
}
define i64 @umull_ldr_b(ptr %x0, i8 %x1) {
-; CHECK-SD-LABEL: umull_ldr_b:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xff
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr_b:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xff
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr_b:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xff
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i32, ptr %x0
%zext = zext i32 %ext64 to i64
@@ -1384,18 +1353,11 @@ entry:
}
define i64 @umull_ldr2_w(ptr %x0, i32 %x1) {
-; CHECK-SD-LABEL: umull_ldr2_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1405,19 +1367,12 @@ entry:
}
define i64 @umull_ldr2_ldr2(ptr %x0, ptr %x1) {
-; CHECK-SD-LABEL: umull_ldr2_ldr2:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: ldr w9, [x1]
-; CHECK-SD-NEXT: umull x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_ldr2:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: ldr w9, [x1]
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_ldr2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: ldr w9, [x1]
+; CHECK-NEXT: umull x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1428,18 +1383,11 @@ entry:
}
define i64 @umull_ldr2_d(ptr %x0, i64 %x1) {
-; CHECK-SD-LABEL: umull_ldr2_d:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umull x0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umull_ldr2_d:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: mul x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umull_ldr2_d:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umull x0, w8, w1
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1449,21 +1397,13 @@ entry:
}
define i64 @umaddl_ldrb_h(ptr %x0, i16 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1474,21 +1414,13 @@ entry:
}
define i64 @umaddl_ldrb_h_commuted(ptr %x0, i16 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrb_h_commuted:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umaddl x0, w9, w8, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrb_h_commuted:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: madd x0, x9, x8, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrb_h_commuted:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umaddl x0, w9, w8, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1499,18 +1431,11 @@ entry:
}
define i64 @umaddl_ldrh_w(ptr %x0, i32 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldrh_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrh w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldrh_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrh w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldrh_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrh w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i16, ptr %x0
%zext = zext i16 %ext64 to i64
@@ -1521,21 +1446,13 @@ entry:
}
define i64 @umaddl_ldr_b(ptr %x0, i8 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr_b:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xff
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr_b:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xff
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr_b:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xff
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i32, ptr %x0
%zext = zext i32 %ext64 to i64
@@ -1546,18 +1463,11 @@ entry:
}
define i64 @umaddl_ldr2_w(ptr %x0, i32 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_w:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_w:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_w:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1568,19 +1478,12 @@ entry:
}
define i64 @umaddl_ldr2_ldr2(ptr %x0, ptr %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_ldr2:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: ldr w9, [x1]
-; CHECK-SD-NEXT: umaddl x0, w8, w9, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_ldr2:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: ldr w9, [x1]
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_ldr2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: ldr w9, [x1]
+; CHECK-NEXT: umaddl x0, w8, w9, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1592,18 +1495,11 @@ entry:
}
define i64 @umaddl_ldr2_d(ptr %x0, i64 %x1, i64 %x2) {
-; CHECK-SD-LABEL: umaddl_ldr2_d:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldr w8, [x0]
-; CHECK-SD-NEXT: umaddl x0, w8, w1, x2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umaddl_ldr2_d:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldr w8, [x0]
-; CHECK-GI-NEXT: mov w9, w1
-; CHECK-GI-NEXT: madd x0, x8, x9, x2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umaddl_ldr2_d:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldr w8, [x0]
+; CHECK-NEXT: umaddl x0, w8, w1, x2
+; CHECK-NEXT: ret
entry:
%ext64 = load i64, ptr %x0
%and = and i64 %ext64, 4294967295
@@ -1614,21 +1510,13 @@ entry:
}
define i64 @umnegl_ldrb_h(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umnegl_ldrb_h:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ldrb w8, [x0]
-; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-SD-NEXT: and x9, x1, #0xffff
-; CHECK-SD-NEXT: umnegl x0, w8, w9
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: umnegl_ldrb_h:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: ldrb w8, [x0]
-; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1
-; CHECK-GI-NEXT: and x9, x1, #0xffff
-; CHECK-GI-NEXT: mneg x0, x8, x9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: umnegl_ldrb_h:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ldrb w8, [x0]
+; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT: and x9, x1, #0xffff
+; CHECK-NEXT: umnegl x0, w8, w9
+; CHECK-NEXT: ret
entry:
%ext64 = load i8, ptr %x0
%zext = zext i8 %ext64 to i64
@@ -1639,21 +1527,13 @@ entry:
}
define i64 @umnegl_ldrb_h_commuted(ptr %x0, i16 %x1) {
-; CHECK-SD-LABEL: umnegl_ldrb_h...
[truncated]
|
llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some TableGen tests for this?
You can write a pattern that triggers these new opcode then check everything is where it belongs
llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
Outdated
Show resolved
Hide resolved
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - the AArch64 updates all look OK to me.
b52dc6f
to
ba567c1
Compare
.value_or(std::string()) | ||
.empty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.value_or(std::string()) | |
.empty()); | |
.has_value() |
or just use the operator bool()
, std::optional
evaluates to true/false depending on whether there is a value
std::string TreePredicateFn::getGISelLeafPredicateCode() const { | ||
return PatFragRec->getRecord() | ||
->getValueAsOptionalString("GISelLeafPredicateCode") | ||
.value_or(std::string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.value_or(std::string()) | |
.value_or(StringRef()) |
if (Predicate.hasGISelLeafPredicateCode()) | ||
return "GICXXPred_MO_" + Predicate.getFnName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for both cases to be true somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible if both fields are assigned values in a PatLeaf. I'll add in a check against that to prevent it from happening
…and GISelLeafPredicateCode on the same PatLeaf
Previously PatLeafs could not be imported, causing the following warnings to be emitted when running tblgen with
-warn-on-skipped-patterns:
These changes allow the patterns to now be imported successfully.