<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Reid,<div class=""><br class=""></div><div class="">Sorry for the slow reply, I was out of the office most of the day. Thanks for fixing this.</div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 16 Oct 2017, at 13:33, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">This broke the MSVC 2017 build. It has something to do with the relative order of instantiation and specialization of addPredicate. I tried to fix this in r315930, which was broken, and r315932, which should fix it without breaking the build elsewhere.</div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sun, Oct 15, 2017 at 5:56 PM, Daniel Sanders via llvm-commits <span dir="ltr" class=""><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dsanders<br class="">
Date: Sun Oct 15 17:56:30 2017<br class="">
New Revision: 315884<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=315884&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=315884&view=rev</a><br class="">
Log:<br class="">
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks<br class="">
<br class="">
Summary:<br class="">
This includes some context-sensitivity in the MVT to LLT conversion so that<br class="">
pointer types are tested correctly.<br class="">
FIXME: I'm not happy with the way this is done since everything is a<br class="">
       special-case. I've yet to find a reasonable way to implement it.<br class="">
<br class="">
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64<br class="">
loads. This is fixed in the next patch and as such they should be committed<br class="">
together, I've posted them separately to help with the review.<br class="">
<br class="">
Depends on D37456<br class="">
<br class="">
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar<br class="">
<br class="">
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb<br class="">
<br class="">
Differential Revision: <a href="https://reviews.llvm.org/D37457" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D37457</a><br class="">
<br class="">
Modified:<br class="">
    llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelector.h<br class="">
    llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelectorImpl.h<br class="">
    llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/select-<wbr class="">load.mir<br class="">
    llvm/trunk/test/TableGen/<wbr class="">GlobalISelEmitter.td<br class="">
    llvm/trunk/utils/TableGen/<wbr class="">GlobalISelEmitter.cpp<br class="">
<br class="">
Modified: llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelector.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=315884&r1=315883&r2=315884&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/include/<wbr class="">llvm/CodeGen/GlobalISel/<wbr class="">InstructionSelector.h?rev=<wbr class="">315884&r1=315883&r2=315884&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelector.h (original)<br class="">
+++ llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelector.h Sun Oct 15 17:56:30 2017<br class="">
@@ -117,6 +117,11 @@ enum {<br class="">
   /// - OpIdx - Operand index<br class="">
   /// - Expected type<br class="">
   GIM_CheckType,<br class="">
+  /// Check the type of a pointer to any address space.<br class="">
+  /// - InsnID - Instruction ID<br class="">
+  /// - OpIdx - Operand index<br class="">
+  /// - SizeInBits - The size of the pointer value in bits.<br class="">
+  GIM_CheckPointerToAny,<br class="">
   /// Check the register bank for the specified operand<br class="">
   /// - InsnID - Instruction ID<br class="">
   /// - OpIdx - Operand index<br class="">
<br class="">
Modified: llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelectorImpl.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h?rev=315884&r1=315883&r2=315884&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/include/<wbr class="">llvm/CodeGen/GlobalISel/<wbr class="">InstructionSelectorImpl.h?rev=<wbr class="">315884&r1=315883&r2=315884&<wbr class="">view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelectorImpl.h (original)<br class="">
+++ llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/<wbr class="">InstructionSelectorImpl.h Sun Oct 15 17:56:30 2017<br class="">
@@ -244,7 +244,21 @@ bool InstructionSelector::<wbr class="">executeMatchTa<br class="">
       }<br class="">
       break;<br class="">
     }<br class="">
-<br class="">
+    case GIM_CheckPointerToAny: {<br class="">
+      int64_t InsnID = MatchTable[CurrentIdx++];<br class="">
+      int64_t OpIdx = MatchTable[CurrentIdx++];<br class="">
+      int64_t SizeInBits = MatchTable[CurrentIdx++];<br class="">
+      DEBUG(dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs[" << InsnID<br class="">
+                   << "]->getOperand(" << OpIdx<br class="">
+                   << "), SizeInBits=" << SizeInBits << ")\n");<br class="">
+      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");<br class="">
+      const LLT &Ty = MRI.getType(State.MIs[InsnID]-<wbr class="">>getOperand(OpIdx).getReg());<br class="">
+      if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) {<br class="">
+        if (handleReject() == RejectAndGiveUp)<br class="">
+          return false;<br class="">
+      }<br class="">
+      break;<br class="">
+    }<br class="">
     case GIM_CheckRegBankForClass: {<br class="">
       int64_t InsnID = MatchTable[CurrentIdx++];<br class="">
       int64_t OpIdx = MatchTable[CurrentIdx++];<br class="">
<br class="">
Modified: llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/select-<wbr class="">load.mir<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-load.mir?rev=315884&r1=315883&r2=315884&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/test/<wbr class="">CodeGen/AArch64/GlobalISel/<wbr class="">select-load.mir?rev=315884&r1=<wbr class="">315883&r2=315884&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/select-<wbr class="">load.mir (original)<br class="">
+++ llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/select-<wbr class="">load.mir Sun Oct 15 17:56:30 2017<br class="">
@@ -1,5 +1,9 @@<br class="">
 # RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s<br class="">
<br class="">
+# This patch temporarily causes LD1Onev1d to match instead of LDRDui on a<br class="">
+# couple functions. A patch to support iPTR will follow that fixes this.<br class="">
+# XFAIL: *<br class="">
+<br class="">
 --- |<br class="">
   target datalayout = "e-m:o-i64:64-i128:128-n32:64-<wbr class="">S128"<br class="">
<br class="">
@@ -28,6 +32,7 @@<br class="">
   define void @load_gep_64_s16_fpr(i16* %addr) { ret void }<br class="">
   define void @load_gep_32_s8_fpr(i8* %addr) { ret void }<br class="">
<br class="">
+  define void @load_v2s32(i64 *%addr) { ret void }<br class="">
 ...<br class="">
<br class="">
 ---<br class="">
@@ -513,3 +518,28 @@ body:             |<br class="">
     %3(s8) = G_LOAD %2 :: (load 1 from %ir.addr)<br class="">
     %b0 = COPY %3<br class="">
 ...<br class="">
+---<br class="">
+# CHECK-LABEL: name: load_v2s32<br class="">
+name:            load_v2s32<br class="">
+legalized:       true<br class="">
+regBankSelected: true<br class="">
+<br class="">
+# CHECK:      registers:<br class="">
+# CHECK-NEXT:  - { id: 0, class: gpr64sp, preferred-register: '' }<br class="">
+# CHECK-NEXT:  - { id: 1, class: fpr64, preferred-register: '' }<br class="">
+registers:<br class="">
+  - { id: 0, class: gpr }<br class="">
+  - { id: 1, class: fpr }<br class="">
+<br class="">
+# CHECK:  body:<br class="">
+# CHECK:    %0 = COPY %x0<br class="">
+# CHECK:    %1 = LD1Onev2s %0<br class="">
+# CHECK:    %d0 = COPY %1<br class="">
+body:             |<br class="">
+  bb.0:<br class="">
+    liveins: %x0<br class="">
+<br class="">
+    %0(p0) = COPY %x0<br class="">
+    %1(<2 x s32>) = G_LOAD %0 :: (load 4 from %ir.addr)<br class="">
+    %d0 = COPY %1(<2 x s32>)<br class="">
+...<br class="">
<br class="">
Modified: llvm/trunk/test/TableGen/<wbr class="">GlobalISelEmitter.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=315884&r1=315883&r2=315884&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/test/<wbr class="">TableGen/GlobalISelEmitter.td?<wbr class="">rev=315884&r1=315883&r2=<wbr class="">315884&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- llvm/trunk/test/TableGen/<wbr class="">GlobalISelEmitter.td (original)<br class="">
+++ llvm/trunk/test/TableGen/<wbr class="">GlobalISelEmitter.td Sun Oct 15 17:56:30 2017<br class="">
@@ -814,9 +814,29 @@ def MOVimm : I<(outs GPR32:$dst), (ins i<br class="">
 def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>;<br class="">
 def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;<br class="">
<br class="">
-//===- Test a pattern with an MBB operand. ------------------------------<wbr class="">--===//<br class="">
+//===- Test a simple pattern with inferred pointer operands. ---------------===//<br class="">
<br class="">
 // CHECK-NEXT:  GIM_Try, /*On fail goto*//*Label 22*/ [[LABEL:[0-9]+]],<br class="">
+// CHECK-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,<br class="">
+// CHECK-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,<br class="">
+// CHECK-NEXT:    GIM_CheckNonAtomic, /*MI*/0,<br class="">
+// CHECK-NEXT:    // MIs[0] dst<br class="">
+// CHECK-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,<br class="">
+// CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::<wbr class="">GPR32RegClassID,<br class="">
+// CHECK-NEXT:    // MIs[0] src1<br class="">
+// CHECK-NEXT:    GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,<br class="">
+// CHECK-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::<wbr class="">GPR32RegClassID,<br class="">
+// CHECK-NEXT:    // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_<wbr class="">unindexedload>><<P:Predicate_<wbr class="">load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<br class="">
+// CHECK-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,<br class="">
+// CHECK-NEXT:    GIR_<wbr class="">ConstrainSelectedInstOperands, /*InsnID*/0,<br class="">
+// CHECK-NEXT:    GIR_Done,<br class="">
+// CHECK-NEXT:  // Label 22: @[[LABEL]]<br class="">
+<br class="">
+def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),<br class="">
+            [(set GPR32:$dst, (load GPR32:$src1))]>;<br class="">
+//===- Test a pattern with an MBB operand. ------------------------------<wbr class="">--===//<br class="">
+<br class="">
+// CHECK-NEXT:  GIM_Try, /*On fail goto*//*Label 23*/ [[LABEL:[0-9]+]],<br class="">
 // CHECK-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/1,<br class="">
 // CHECK-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,<br class="">
 // CHECK-NEXT:    // MIs[0] target<br class="">
@@ -825,7 +845,7 @@ def MOVfpimmz : I<(outs FPR32:$dst), (in<br class="">
 // CHECK-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR,<br class="">
 // CHECK-NEXT:    GIR_<wbr class="">ConstrainSelectedInstOperands, /*InsnID*/0,<br class="">
 // CHECK-NEXT:    GIR_Done,<br class="">
-// CHECK-NEXT:  // Label 22: @[[LABEL]]<br class="">
+// CHECK-NEXT:  // Label 23: @[[LABEL]]<br class="">
<br class="">
 def BR : I<(outs), (ins unknown:$target),<br class="">
             [(br bb:$target)]>;<br class="">
<br class="">
Modified: llvm/trunk/utils/TableGen/<wbr class="">GlobalISelEmitter.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=315884&r1=315883&r2=315884&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/llvm/trunk/utils/<wbr class="">TableGen/GlobalISelEmitter.<wbr class="">cpp?rev=315884&r1=315883&r2=<wbr class="">315884&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- llvm/trunk/utils/TableGen/<wbr class="">GlobalISelEmitter.cpp (original)<br class="">
+++ llvm/trunk/utils/TableGen/<wbr class="">GlobalISelEmitter.cpp Sun Oct 15 17:56:30 2017<br class="">
@@ -103,6 +103,12 @@ public:<br class="">
       OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();<br class="">
       return;<br class="">
     }<br class="">
+    if (Ty.isPointer()) {<br class="">
+      OS << "GILLT_p" << Ty.getAddressSpace();<br class="">
+      if (Ty.getSizeInBits() > 0)<br class="">
+        OS << "s" << Ty.getSizeInBits();<br class="">
+      return;<br class="">
+    }<br class="">
     llvm_unreachable("Unhandled LLT");<br class="">
   }<br class="">
<br class="">
@@ -116,6 +122,11 @@ public:<br class="">
          << Ty.getScalarSizeInBits() << ")";<br class="">
       return;<br class="">
     }<br class="">
+    if (Ty.isPointer() && Ty.getSizeInBits() > 0) {<br class="">
+      OS << "LLT::pointer(" << Ty.getAddressSpace() << ", "<br class="">
+         << Ty.getSizeInBits() << ")";<br class="">
+      return;<br class="">
+    }<br class="">
     llvm_unreachable("Unhandled LLT");<br class="">
   }<br class="">
<br class="">
@@ -152,9 +163,11 @@ class InstructionMatcher;<br class="">
 /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).<br class="">
 static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {<br class="">
   MVT VT(SVT);<br class="">
+<br class="">
   if (VT.isVector() && VT.getVectorNumElements() != 1)<br class="">
     return LLTCodeGen(<br class="">
         LLT::vector(VT.<wbr class="">getVectorNumElements(), VT.getScalarSizeInBits()));<br class="">
+<br class="">
   if (VT.isInteger() || VT.isFloatingPoint())<br class="">
     return LLTCodeGen(LLT::scalar(VT.<wbr class="">getSizeInBits()));<br class="">
   return None;<br class="">
@@ -228,6 +241,11 @@ static Error isTrivialOperatorNode(const<br class="">
     if (Predicate.isImmediatePattern(<wbr class="">))<br class="">
       continue;<br class="">
<br class="">
+    if (Predicate.isLoad() && Predicate.isUnindexed())<br class="">
+      continue;<br class="">
+<br class="">
+    if (Predicate.isNonExtLoad())<br class="">
+      continue;<br class="">
     HasUnsupportedPredicate = true;<br class="">
     Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";<br class="">
     Separator = ", ";<br class="">
@@ -661,6 +679,7 @@ public:<br class="">
     OPM_Int,<br class="">
     OPM_LiteralInt,<br class="">
     OPM_LLT,<br class="">
+    OPM_PointerToAny,<br class="">
     OPM_RegBank,<br class="">
     OPM_MBB,<br class="">
   };<br class="">
@@ -748,6 +767,37 @@ public:<br class="">
<br class="">
 std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;<br class="">
<br class="">
+/// Generates code to check that an operand is a pointer to any address space.<br class="">
+///<br class="">
+/// In SelectionDAG, the types did not describe pointers or address spaces. As a<br class="">
+/// result, iN is used to describe a pointer of N bits to any address space and<br class="">
+/// PatFrag predicates are typically used to constrain the address space. There's<br class="">
+/// no reliable means to derive the missing type information from the pattern so<br class="">
+/// imported rules must test the components of a pointer separately.<br class="">
+///<br class="">
+/// SizeInBits must be non-zero and the matched pointer must be that size.<br class="">
+/// TODO: Add support for iPTR via SizeInBits==0 and a subtarget query.<br class="">
+class PointerToAnyOperandMatcher : public OperandPredicateMatcher {<br class="">
+protected:<br class="">
+  unsigned SizeInBits;<br class="">
+<br class="">
+public:<br class="">
+  PointerToAnyOperandMatcher(<wbr class="">unsigned SizeInBits)<br class="">
+      : OperandPredicateMatcher(OPM_<wbr class="">PointerToAny), SizeInBits(SizeInBits) {}<br class="">
+<br class="">
+  static bool classof(const OperandPredicateMatcher *P) {<br class="">
+    return P->getKind() == OPM_PointerToAny;<br class="">
+  }<br class="">
+<br class="">
+  void emitPredicateOpcodes(<wbr class="">MatchTable &Table, RuleMatcher &Rule,<br class="">
+                            unsigned InsnVarID, unsigned OpIdx) const override {<br class="">
+    Table << MatchTable::Opcode("GIM_<wbr class="">CheckPointerToAny") << MatchTable::Comment("MI")<br class="">
+          << MatchTable::IntValue(<wbr class="">InsnVarID) << MatchTable::Comment("Op")<br class="">
+          << MatchTable::IntValue(OpIdx) << MatchTable::Comment("<wbr class="">SizeInBits")<br class="">
+          << MatchTable::IntValue(<wbr class="">SizeInBits) << MatchTable::LineBreak;<br class="">
+  }<br class="">
+};<br class="">
+<br class="">
 /// Generates code to check that an operand is a particular target constant.<br class="">
 class ComplexPatternOperandMatcher : public OperandPredicateMatcher {<br class="">
 protected:<br class="">
@@ -927,6 +977,22 @@ public:<br class="">
<br class="">
   InstructionMatcher &getInstructionMatcher() const { return Insn; }<br class="">
<br class="">
+  Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,<br class="">
+                              bool OperandIsAPointer) {<br class="">
+    auto OpTyOrNone = VTy.isMachineValueType()<br class="">
+                          ? MVTToLLT(VTy.<wbr class="">getMachineValueType().<wbr class="">SimpleTy)<br class="">
+                          : None;<br class="">
+    if (!OpTyOrNone)<br class="">
+      return failedImport("unsupported type");<br class="">
+<br class="">
+    if (OperandIsAPointer)<br class="">
+      addPredicate<<wbr class="">PointerToAnyOperandMatcher>(<br class="">
+          OpTyOrNone->get().<wbr class="">getSizeInBits());<br class="">
+    else<br class="">
+      addPredicate<<wbr class="">LLTOperandMatcher>(*<wbr class="">OpTyOrNone);<br class="">
+    return Error::success();<br class="">
+  }<br class="">
+<br class="">
   /// Emit MatchTable opcodes to capture instructions into the MIs table.<br class="">
   void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,<br class="">
                           unsigned InsnVarID) const {<br class="">
@@ -2070,7 +2136,8 @@ private:<br class="">
   Error importComplexPatternOperandMat<wbr class="">cher(OperandMatcher &OM, Record *R,<br class="">
                                            unsigned &TempOpIdx) const;<br class="">
   Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,<br class="">
-                           const TreePatternNode *SrcChild, unsigned OpIdx,<br class="">
+                           const TreePatternNode *SrcChild,<br class="">
+                           bool OperandIsAPointer, unsigned OpIdx,<br class="">
                            unsigned &TempOpIdx) const;<br class="">
   Expected<BuildMIAction &><br class="">
   createAndImportInstructionRend<wbr class="">erer(RuleMatcher &M, const TreePatternNode *Dst,<br class="">
@@ -2164,17 +2231,12 @@ Expected<InstructionMatcher &> GlobalISe<br class="">
<br class="">
   unsigned OpIdx = 0;<br class="">
   for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {<br class="">
-    auto OpTyOrNone = VTy.isMachineValueType()<br class="">
-                          ? MVTToLLT(VTy.<wbr class="">getMachineValueType().<wbr class="">SimpleTy)<br class="">
-                          : None;<br class="">
-    if (!OpTyOrNone)<br class="">
-      return failedImport(<br class="">
-          "Result of Src pattern operator has an unsupported type");<br class="">
-<br class="">
     // Results don't have a name unless they are the root node. The caller will<br class="">
     // set the name if appropriate.<br class="">
     OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++<wbr class="">, "", TempOpIdx);<br class="">
-    OM.addPredicate<<wbr class="">LLTOperandMatcher>(*<wbr class="">OpTyOrNone);<br class="">
+    if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))<br class="">
+      return failedImport(toString(std::<wbr class="">move(Error)) +<br class="">
+                          " for result of Src pattern operator");<br class="">
   }<br class="">
<br class="">
   for (const auto &Predicate : Src->getPredicateFns()) {<br class="">
@@ -2186,6 +2248,25 @@ Expected<InstructionMatcher &> GlobalISe<br class="">
       continue;<br class="">
     }<br class="">
<br class="">
+    // No check required. A G_LOAD is an unindexed load.<br class="">
+    if (Predicate.isLoad() && Predicate.isUnindexed())<br class="">
+      continue;<br class="">
+<br class="">
+    // No check required. G_LOAD by itself is a non-extending load.<br class="">
+    if (Predicate.isNonExtLoad())<br class="">
+      continue;<br class="">
+<br class="">
+    if (Predicate.isLoad() && Predicate.getMemoryVT() != nullptr) {<br class="">
+      Optional<LLTCodeGen> MemTyOrNone =<br class="">
+          MVTToLLT(getValueType(<wbr class="">Predicate.getMemoryVT()));<br class="">
+<br class="">
+      if (!MemTyOrNone)<br class="">
+        return failedImport("MemVT could not be converted to LLT");<br class="">
+<br class="">
+      InsnMatcher.getOperand(0).<wbr class="">addPredicate<<wbr class="">LLTOperandMatcher>(<wbr class="">MemTyOrNone.getValue());<br class="">
+      continue;<br class="">
+    }<br class="">
+<br class="">
     return failedImport("Src pattern child has predicate (" +<br class="">
                         explainPredicates(Src) + ")");<br class="">
   }<br class="">
@@ -2217,6 +2298,13 @@ Expected<InstructionMatcher &> GlobalISe<br class="">
     for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {<br class="">
       TreePatternNode *SrcChild = Src->getChild(i);<br class="">
<br class="">
+      // SelectionDAG allows pointers to be represented with iN since it doesn't<br class="">
+      // distinguish between pointers and integers but they are different types in GlobalISel.<br class="">
+      // Coerce integers to pointers to address space 0 if the context indicates a pointer.<br class="">
+      // TODO: Find a better way to do this, SDTCisPtrTy?<br class="">
+      bool OperandIsAPointer =<br class="">
+          SrcGIOrNull->TheDef->getName() == "G_LOAD" && i == 0;<br class="">
+<br class="">
       // For G_INTRINSIC/G_INTRINSIC_W_<wbr class="">SIDE_EFFECTS, the operand immediately<br class="">
       // following the defs is an intrinsic ID.<br class="">
       if ((SrcGIOrNull->TheDef-><wbr class="">getName() == "G_INTRINSIC" ||<br class="">
@@ -2232,8 +2320,9 @@ Expected<InstructionMatcher &> GlobalISe<br class="">
         return failedImport("Expected IntInit containing instrinsic ID)");<br class="">
       }<br class="">
<br class="">
-      if (auto Error = importChildMatcher(Rule, InsnMatcher, SrcChild, OpIdx++,<br class="">
-                                          TempOpIdx))<br class="">
+      if (auto Error =<br class="">
+              importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,<br class="">
+                                 OpIdx++, TempOpIdx))<br class="">
         return std::move(Error);<br class="">
     }<br class="">
   }<br class="">
@@ -2256,6 +2345,7 @@ Error GlobalISelEmitter::<wbr class="">importComplexPa<br class="">
 Error GlobalISelEmitter::<wbr class="">importChildMatcher(RuleMatcher &Rule,<br class="">
                                             InstructionMatcher &InsnMatcher,<br class="">
                                             const TreePatternNode *SrcChild,<br class="">
+                                            bool OperandIsAPointer,<br class="">
                                             unsigned OpIdx,<br class="">
                                             unsigned &TempOpIdx) const {<br class="">
   OperandMatcher &OM =<br class="">
@@ -2278,12 +2368,10 @@ Error GlobalISelEmitter::<wbr class="">importChildMatc<br class="">
     }<br class="">
   }<br class="">
<br class="">
-  Optional<LLTCodeGen> OpTyOrNone = None;<br class="">
-  if (ChildTypes.front().<wbr class="">isMachineValueType())<br class="">
-    OpTyOrNone = MVTToLLT(ChildTypes.front().<wbr class="">getMachineValueType().<wbr class="">SimpleTy);<br class="">
-  if (!OpTyOrNone)<br class="">
-    return failedImport("Src operand has an unsupported type (" + to_string(*SrcChild) + ")");<br class="">
-  OM.addPredicate<<wbr class="">LLTOperandMatcher>(*<wbr class="">OpTyOrNone);<br class="">
+  if (auto Error =<br class="">
+          OM.addTypeCheckPredicate(<wbr class="">ChildTypes.front(), OperandIsAPointer))<br class="">
+    return failedImport(toString(std::<wbr class="">move(Error)) + " for Src operand (" +<br class="">
+                        to_string(*SrcChild) + ")");<br class="">
<br class="">
   // Check for nested instructions.<br class="">
   if (!SrcChild->isLeaf()) {<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></body></html>