[llvm] r279566 - GlobalISel: legalize integer comparisons on AArch64.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 23 14:01:27 PDT 2016


Author: tnorthover
Date: Tue Aug 23 16:01:26 2016
New Revision: 279566

URL: http://llvm.org/viewvc/llvm-project?rev=279566&view=rev
Log:
GlobalISel: legalize integer comparisons on AArch64.

Next step is doing both legalizations at the same time! Marvel at GlobalISel's
cunning.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=279566&r1=279565&r2=279566&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Tue Aug 23 16:01:26 2016
@@ -156,6 +156,28 @@ public:
   /// \return The newly created instruction.
   MachineInstrBuilder buildAnyExtend(LLT Ty, unsigned Res, unsigned Op);
 
+  /// Build and insert \p Res<def> = G_SEXT \p { DstTy, SrcTy }\p Op
+  ///
+  /// G_SEXT produces a register of the specified width, with bits 0 to
+  /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are duplicated from the
+  /// high bit of \p Op (i.e. 2s-complement sign extended).
+  ///
+  /// \pre setBasicBlock or setMI must have been called.
+  ///
+  /// \return The newly created instruction.
+  MachineInstrBuilder buildSExt(ArrayRef<LLT> Tys, unsigned Res, unsigned Op);
+
+  /// Build and insert \p Res<def> = G_ZEXT \p { DstTy, SrcTy } \p Op
+  ///
+  /// G_ZEXT produces a register of the specified width, with bits 0 to
+  /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are 0. For a vector
+  /// register, each element is extended individually.
+  ///
+  /// \pre setBasicBlock or setMI must have been called.
+  ///
+  /// \return The newly created instruction.
+  MachineInstrBuilder buildZExt(ArrayRef<LLT> Tys, unsigned Res, unsigned Op);
+
   /// Build and insert G_BR unsized \p Dest
   ///
   /// G_BR is an unconditional branch to \p Dest.

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=279566&r1=279565&r2=279566&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Tue Aug 23 16:01:26 2016
@@ -146,6 +146,16 @@ MachineInstrBuilder MachineIRBuilder::bu
   return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op);
 }
 
+MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
+                                                unsigned Op) {
+  return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
+}
+
+MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
+                                                unsigned Op) {
+  return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
+}
+
 MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<LLT> ResTys,
                                                    ArrayRef<unsigned> Results,
                                                    ArrayRef<uint64_t> Indices,

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp?rev=279566&r1=279565&r2=279566&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp Tue Aug 23 16:01:26 2016
@@ -107,8 +107,6 @@ MachineLegalizeHelper::narrowScalar(Mach
 MachineLegalizeHelper::LegalizeResult
 MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
                                    LLT WideTy) {
-  assert(TypeIdx == 0 && "don't know how to handle secondary types yet");
-
   unsigned WideSize = WideTy.getSizeInBits();
   MIRBuilder.setInstr(MI);
 
@@ -180,6 +178,40 @@ MachineLegalizeHelper::widenScalar(Machi
     MI.eraseFromParent();
     return Legalized;
   }
+  case TargetOpcode::G_ICMP: {
+    if (TypeIdx == 0) {
+      unsigned TstExt = MRI.createGenericVirtualRegister(WideSize);
+      MIRBuilder.buildICmp(
+          {WideTy, MI.getType(1)},
+          static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
+          TstExt, MI.getOperand(2).getReg(), MI.getOperand(3).getReg());
+      MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), TstExt);
+      MI.eraseFromParent();
+      return Legalized;
+    } else {
+      bool IsSigned = CmpInst::isSigned(
+          static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
+      unsigned Op0Ext = MRI.createGenericVirtualRegister(WideSize);
+      unsigned Op1Ext = MRI.createGenericVirtualRegister(WideSize);
+      if (IsSigned) {
+        MIRBuilder.buildSExt({WideTy, MI.getType(1)}, Op0Ext,
+                             MI.getOperand(2).getReg());
+        MIRBuilder.buildSExt({WideTy, MI.getType(1)}, Op1Ext,
+                             MI.getOperand(3).getReg());
+      } else {
+        MIRBuilder.buildZExt({WideTy, MI.getType(1)}, Op0Ext,
+                             MI.getOperand(2).getReg());
+        MIRBuilder.buildZExt({WideTy, MI.getType(1)}, Op1Ext,
+                             MI.getOperand(3).getReg());
+      }
+      MIRBuilder.buildICmp(
+          {MI.getType(0), WideTy},
+          static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
+          MI.getOperand(0).getReg(), Op0Ext, Op1Ext);
+      MI.eraseFromParent();
+      return Legalized;
+    }
+  }
   }
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=279566&r1=279565&r2=279566&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Tue Aug 23 16:01:26 2016
@@ -1522,7 +1522,7 @@ bool MIParser::parsePredicateOperand(Mac
 
   lex();
   Dest = MachineOperand::CreatePredicate(Pred);
-  if (!expectAndConsume(MIToken::rparen))
+  if (expectAndConsume(MIToken::rparen))
     return error("predicate should be terminated by ')'.");
 
   return false;

Modified: llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp?rev=279566&r1=279565&r2=279566&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp Tue Aug 23 16:01:26 2016
@@ -73,6 +73,19 @@ AArch64MachineLegalizer::AArch64MachineL
 
   setAction({TargetOpcode::G_FCONSTANT, s16}, WidenScalar);
 
+  // Comparisons: we produce a result in s32 with undefined high-bits for
+  // now. Values being compared can be 32 or 64-bits.
+  for (auto CmpOp : { G_ICMP }) {
+    setAction({CmpOp, 0, s32}, Legal);
+    setAction({CmpOp, 1, s32}, Legal);
+    setAction({CmpOp, 1, s64}, Legal);
+
+    for (auto Ty : {s1, s8, s16}) {
+      setAction({CmpOp, 0, Ty}, WidenScalar);
+      setAction({CmpOp, 1, Ty}, WidenScalar);
+    }
+  }
+
   // Control-flow
   setAction({G_BR, LLT::unsized()}, Legal);
   setAction({G_BRCOND, s32}, Legal);




More information about the llvm-commits mailing list