[llvm-commits] [llvm] r143559 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-icmp.ll

Chad Rosier mcrosier at apple.com
Wed Nov 2 11:08:25 PDT 2011


Author: mcrosier
Date: Wed Nov  2 13:08:25 2011
New Revision: 143559

URL: http://llvm.org/viewvc/llvm-project?rev=143559&view=rev
Log:
Add support for comparing integer non-legal types.

Added:
    llvm/trunk/test/CodeGen/ARM/fast-isel-icmp.ll
Modified:
    llvm/trunk/lib/Target/ARM/ARMFastISel.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=143559&r1=143558&r2=143559&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Nov  2 13:08:25 2011
@@ -174,7 +174,8 @@
   private:
     bool isTypeLegal(Type *Ty, MVT &VT);
     bool isLoadTypeLegal(Type *Ty, MVT &VT);
-    bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value);
+    bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
+                    bool isZExt);
     bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr);
     bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
     bool ARMComputeAddress(const Value *Obj, Address &Addr);
@@ -1119,7 +1120,7 @@
       if (ARMPred == ARMCC::AL) return false;
 
       // Emit the compare.
-      if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
+      if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
         return false;
 
       unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
@@ -1189,19 +1190,19 @@
   return true;
 }
 
-bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) {
-  MVT VT;
+bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
+                             bool isZExt) {
   Type *Ty = Src1Value->getType();
-  if (!isTypeLegal(Ty, VT))
-    return false;
+  EVT SrcVT = TLI.getValueType(Ty, true);
+  if (!SrcVT.isSimple()) return false;
 
   bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
   if (isFloat && !Subtarget->hasVFP2())
     return false;
 
   unsigned CmpOpc;
-  switch (VT.SimpleTy) {
-    // TODO: Add support for non-legal types (i.e., i1, i8, i16).
+  bool needsExt = false;
+  switch (SrcVT.getSimpleVT().SimpleTy) {
     default: return false;
     // TODO: Verify compares.
     case MVT::f32:
@@ -1210,19 +1211,36 @@
     case MVT::f64:
       CmpOpc = ARM::VCMPED;
       break;
+    case MVT::i1:
+    case MVT::i8:
+    case MVT::i16:
+      needsExt = true;
+    // Intentional fall-through.
     case MVT::i32:
       CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
       break;
   }
 
-  unsigned Src1 = getRegForValue(Src1Value);
-  if (Src1 == 0) return false;
+  unsigned SrcReg1 = getRegForValue(Src1Value);
+  if (SrcReg1 == 0) return false;
 
-  unsigned Src2 = getRegForValue(Src2Value);
-  if (Src2 == 0) return false;
+  unsigned SrcReg2 = getRegForValue(Src2Value);
+  if (SrcReg2 == 0) return false;
+
+  // We have i1, i8, or i16, we need to either zero extend or sign extend.
+  if (needsExt) {
+    unsigned ResultReg;
+    EVT DestVT = MVT::i32;
+    ResultReg = ARMEmitIntExt(SrcVT, SrcReg1, DestVT, isZExt);
+    if (ResultReg == 0) return false;
+    SrcReg1 = ResultReg;
+    ResultReg = ARMEmitIntExt(SrcVT, SrcReg2, DestVT, isZExt);
+    if (ResultReg == 0) return false;
+    SrcReg2 = ResultReg;
+  }
 
   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
-                  .addReg(Src1).addReg(Src2));
+                  .addReg(SrcReg1).addReg(SrcReg2));
 
   // For floating point we need to move the result to a comparison register
   // that we can then use for branches.
@@ -1243,7 +1261,7 @@
   if (ARMPred == ARMCC::AL) return false;
 
   // Emit the compare.
-  if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
+  if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
     return false;
 
   // Now set a register based on the comparison. Explicitly set the predicates
@@ -1962,7 +1980,6 @@
   static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
 
   return true;
-
 }
 
 bool ARMFastISel::SelectTrunc(const Instruction *I) {

Added: llvm/trunk/test/CodeGen/ARM/fast-isel-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-icmp.ll?rev=143559&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fast-isel-icmp.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/fast-isel-icmp.ll Wed Nov  2 13:08:25 2011
@@ -0,0 +1,47 @@
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB
+
+define i32 @icmp_i16_unsigned(i16 %a, i16 %b) nounwind {
+entry:
+; ARM: icmp_i16_unsigned
+; ARM: uxth r0, r0
+; ARM: uxth r1, r1
+; ARM: cmp	r0, r1
+; THUMB: icmp_i16_unsigned
+; THUMB: uxth r0, r0
+; THUMB: uxth r1, r1
+; THUMB: cmp	r0, r1
+  %cmp = icmp ult i16 %a, %b
+  %conv2 = zext i1 %cmp to i32
+  ret i32 %conv2
+}
+
+define i32 @icmp_i8_signed(i8 %a, i8 %b) nounwind {
+entry:
+; ARM: icmp_i8_signed
+; ARM: sxtb r0, r0
+; ARM: sxtb r1, r1
+; ARM: cmp r0, r1
+; THUMB: icmp_i8_signed
+; THUMB: sxtb r0, r0
+; THUMB: sxtb r1, r1
+; THUMB: cmp r0, r1
+  %cmp = icmp sgt i8 %a, %b
+  %conv2 = zext i1 %cmp to i32
+  ret i32 %conv2
+}
+
+define i32 @icmp_i1_unsigned(i1 %a, i1 %b) nounwind {
+entry:
+; ARM: icmp_i1_unsigned
+; ARM: and r0, r0, #1
+; ARM: and r1, r1, #1
+; ARM: cmp r0, r1
+; THUMB: icmp_i1_unsigned
+; THUMB: and r0, r0, #1
+; THUMB: and r1, r1, #1
+; THUMB: cmp r0, r1
+  %cmp = icmp ult i1 %a, %b
+  %conv2 = zext i1 %cmp to i32
+  ret i32 %conv2
+}





More information about the llvm-commits mailing list