]> granicus.if.org Git - llvm/commitdiff
[PowerPC] Enhance the fast selection of cmp instruction and clean up related asserts
authorZi Xuan Wu <wuzish@cn.ibm.com>
Fri, 25 Jan 2019 07:24:59 +0000 (07:24 +0000)
committerZi Xuan Wu <wuzish@cn.ibm.com>
Fri, 25 Jan 2019 07:24:59 +0000 (07:24 +0000)
Fast selection of llvm icmp and fcmp instructions is not handled well about VSX instruction support.

We'd use VSX float comparison instruction instead of non-vsx float comparison instruction
if the operand register class is VSSRC or VSFRC because i32 and i64 are mapped to VSSRC and
VSFRC correspondingly if VSX feature is opened.

If the target does not have corresponding VSX instruction comparison for some type,
just copy VSX-related register to common float register class and use non-vsx comparison instruction.

Differential Revision: https://reviews.llvm.org/D57078

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352174 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCFastISel.cpp
test/CodeGen/PowerPC/fast-isel-cmp-imm.ll

index 3f9a10752bd7afe448c9b54f064f8a3a813b4bfc..a597c5ef6f6e967a555fd8c97bfe3382b984c98d 100644 (file)
@@ -873,7 +873,10 @@ bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
 
   unsigned CmpOpc;
   bool NeedsExt = false;
-  auto RC = MRI.getRegClass(SrcReg1);
+
+  auto RC1 = MRI.getRegClass(SrcReg1);
+  auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) : nullptr;
+
   switch (SrcVT.SimpleTy) {
     default: return false;
     case MVT::f32:
@@ -892,12 +895,18 @@ bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
         }
       } else {
         CmpOpc = PPC::FCMPUS;
-        if (isVSSRCRegClass(RC)) {
+        if (isVSSRCRegClass(RC1)) {
           unsigned TmpReg = createResultReg(&PPC::F4RCRegClass);
           BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
                   TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg1);
           SrcReg1 = TmpReg;
         }
+        if (RC2 && isVSSRCRegClass(RC2)) {
+          unsigned TmpReg = createResultReg(&PPC::F4RCRegClass);
+          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+                  TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg2);
+          SrcReg2 = TmpReg;
+        }
       }
       break;
     case MVT::f64:
@@ -914,7 +923,7 @@ bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
             CmpOpc = PPC::EFDCMPGT;
             break;
         }
-      } else if (isVSFRCRegClass(RC)) {
+      } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
         CmpOpc = PPC::XSCMPUDP;
       } else {
         CmpOpc = PPC::FCMPUD;
index 004b82f09b87aee3d7e3397c20bc7e35599b1a33..df8d37d4d3675e4644cb1a869a35d51dfb4fbbb9 100644 (file)
@@ -1,17 +1,21 @@
-; FIXME: FastISel currently returns false if it hits code that uses VSX
-; registers and with -fast-isel-abort=1 turned on the test case will then fail.
-; When fastisel better supports VSX fix up this test case.
-;
 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck %s --check-prefix=ELF64
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc64le-unknown-linux-gnu -mattr=+vsx | FileCheck %s --check-prefix=VSX
 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc-unknown-linux-gnu -mcpu=e500 -mattr=spe | FileCheck %s --check-prefix=SPE
+
+declare void @foo()
+
 define void @t1a(float %a) nounwind {
 entry:
-; ELF64: t1a
-; SPE: t1a
+; ELF64-LABEL: @t1a
+; SPE-LABEL: @t1a
+; VSX-LABEL: @t1a
   %cmp = fcmp oeq float %a, 0.000000e+00
 ; ELF64: addis
 ; ELF64: lfs
 ; ELF64: fcmpu
+; VSX: addis
+; VSX: lfs
+; VSX: fcmpu
 ; SPE: efscmpeq
   br i1 %cmp, label %if.then, label %if.end
 
@@ -23,16 +27,41 @@ if.end:                                           ; preds = %if.then, %entry
   ret void
 }
 
-declare void @foo()
-
 define void @t1b(float %a) nounwind {
 entry:
-; ELF64: t1b
-; SPE: t1b
+; ELF64-LABEL: @t1b
+; SPE-LABEL: @t1b
+; VSX-LABEL: @t1b
   %cmp = fcmp oeq float %a, -0.000000e+00
 ; ELF64: addis
 ; ELF64: lfs
 ; ELF64: fcmpu
+; VSX: addis
+; VSX: lfs
+; VSX: fcmpu
+; SPE: efscmpeq
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+define void @t1c(float %a) nounwind {
+entry:
+; ELF64-LABEL: @t1c
+; SPE-LABEL: @t1c
+; VSX-LABEL: @t1c
+  %cmp = fcmp oeq float -0.000000e+00, %a
+; ELF64: addis
+; ELF64: lfs
+; ELF64: fcmpu
+; VSX: addis
+; VSX: lfs
+; VSX: fcmpu
 ; SPE: efscmpeq
   br i1 %cmp, label %if.then, label %if.end
 
@@ -46,12 +75,16 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t2a(double %a) nounwind {
 entry:
-; ELF64: t2a
-; SPE: t2a
+; ELF64-LABEL: @t2a
+; SPE-LABEL: @t2a
+; VSX-LABEL: @t2a
   %cmp = fcmp oeq double %a, 0.000000e+00
 ; ELF64: addis
 ; ELF64: lfd
 ; ELF64: fcmpu
+; VSX: addis
+; VSX: lfd
+; VSX: xscmpudp
 ; SPE: efdcmpeq
   br i1 %cmp, label %if.then, label %if.end
 
@@ -65,12 +98,39 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t2b(double %a) nounwind {
 entry:
-; ELF64: t2b
-; SPE: t2b
+; ELF64-LABEL: @t2b
+; SPE-LABEL: @t2b
+; VSX-LABEL: @t2b
   %cmp = fcmp oeq double %a, -0.000000e+00
 ; ELF64: addis
 ; ELF64: lfd
 ; ELF64: fcmpu
+; VSX: addis
+; VSX: lfd
+; VSX: xscmpudp
+; SPE: efdcmpeq
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+define void @t2c(double %a) nounwind {
+entry:
+; ELF64-LABEL: @t2c
+; SPE-LABEL: @t2c
+; VSX-LABEL: @t2c
+  %cmp = fcmp oeq double -0.000000e+00, %a
+; ELF64: addis
+; ELF64: lfd
+; ELF64: fcmpu
+; VSX: addis
+; VSX: lfd
+; VSX: xscmpudp
 ; SPE: efdcmpeq
   br i1 %cmp, label %if.then, label %if.end
 
@@ -84,7 +144,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t4(i8 signext %a) nounwind {
 entry:
-; ELF64t4
+; ELF64-LABEL: @t4
   %cmp = icmp eq i8 %a, -1
 ; ELF64: extsb
 ; ELF64: cmpwi
@@ -100,7 +160,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t5(i8 zeroext %a) nounwind {
 entry:
-; ELF64t5
+; ELF64-LABEL: @t5
   %cmp = icmp eq i8 %a, 1
 ; ELF64: extsb
 ; ELF64: cmpwi
@@ -114,9 +174,25 @@ if.end:                                           ; preds = %if.then, %entry
   ret void
 }
 
+define void @t5a(i8 zeroext %a) nounwind {
+entry:
+; ELF64-LABEL: @t5a
+  %cmp = icmp eq i8 1, %a
+; ELF64: extsb
+; ELF64: cmpw
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
 define void @t6(i16 signext %a) nounwind {
 entry:
-; ELF64t6
+; ELF64-LABEL: @t6
   %cmp = icmp eq i16 %a, -1
 ; ELF64: extsh
 ; ELF64: cmpwi
@@ -132,7 +208,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t7(i16 zeroext %a) nounwind {
 entry:
-; ELF64t7
+; ELF64-LABEL: @t7
   %cmp = icmp eq i16 %a, 1
 ; ELF64: extsh
 ; ELF64: cmpwi
@@ -146,9 +222,25 @@ if.end:                                           ; preds = %if.then, %entry
   ret void
 }
 
+define void @t7a(i16 zeroext %a) nounwind {
+entry:
+; ELF64-LABEL: @t7a
+  %cmp = icmp eq i16 1, %a
+; ELF64: extsh
+; ELF64: cmpw
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
 define void @t8(i32 %a) nounwind {
 entry:
-; ELF64t8
+; ELF64-LABEL: @t8
   %cmp = icmp eq i32 %a, -1
 ; ELF64: cmpwi
   br i1 %cmp, label %if.then, label %if.end
@@ -163,7 +255,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t9(i32 %a) nounwind {
 entry:
-; ELF64t9
+; ELF64-LABEL: @t9
   %cmp = icmp eq i32 %a, 1
 ; ELF64: cmpwi
   br i1 %cmp, label %if.then, label %if.end
@@ -178,7 +270,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t10(i32 %a) nounwind {
 entry:
-; ELF64t10
+; ELF64-LABEL: @t10
   %cmp = icmp eq i32 %a, 384
 ; ELF64: cmpwi
   br i1 %cmp, label %if.then, label %if.end
@@ -193,7 +285,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t11(i32 %a) nounwind {
 entry:
-; ELF64t11
+; ELF64-LABEL: @t11
   %cmp = icmp eq i32 %a, 4096
 ; ELF64: cmpwi
   br i1 %cmp, label %if.then, label %if.end
@@ -206,9 +298,24 @@ if.end:                                           ; preds = %if.then, %entry
   ret void
 }
 
+define void @t11a(i32 %a) nounwind {
+entry:
+; ELF64-LABEL: @t11a
+  %cmp = icmp eq i32 4096, %a
+; ELF64: cmpw
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
 define void @t12(i8 %a) nounwind {
 entry:
-; ELF64t12
+; ELF64-LABEL: @t12
   %cmp = icmp ugt i8 %a, -113
 ; ELF64: clrlwi
 ; ELF64: cmplwi
@@ -224,7 +331,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t13() nounwind ssp {
 entry:
-; ELF64t13
+; ELF64-LABEL: @t13
   %cmp = icmp slt i32 -123, -2147483648
 ; ELF64: li
 ; ELF64: lis
@@ -240,7 +347,7 @@ if.end:                                           ; preds = %entry
 
 define void @t14(i64 %a) nounwind {
 entry:
-; ELF64t14
+; ELF64-LABEL: @t14
   %cmp = icmp eq i64 %a, -1
 ; ELF64: cmpdi
   br i1 %cmp, label %if.then, label %if.end
@@ -255,7 +362,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t15(i64 %a) nounwind {
 entry:
-; ELF64t15
+; ELF64-LABEL: @t15
   %cmp = icmp eq i64 %a, 1
 ; ELF64: cmpdi
   br i1 %cmp, label %if.then, label %if.end
@@ -270,7 +377,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t16(i64 %a) nounwind {
 entry:
-; ELF64t16
+; ELF64-LABEL: @t16
   %cmp = icmp eq i64 %a, 384
 ; ELF64: cmpdi
   br i1 %cmp, label %if.then, label %if.end
@@ -285,7 +392,7 @@ if.end:                                           ; preds = %if.then, %entry
 
 define void @t17(i64 %a) nounwind {
 entry:
-; ELF64t17
+; ELF64-LABEL: @t17
   %cmp = icmp eq i64 %a, 32768
 ; Extra operand so we don't match on cmpdi.
 ; ELF64: cmpd {{[0-9]+}}
@@ -299,3 +406,19 @@ if.end:                                           ; preds = %if.then, %entry
   ret void
 }
 
+define void @t17a(i64 %a) nounwind {
+entry:
+; ELF64-LABEL: @t17a
+  %cmp = icmp eq i64 32768, %a
+; Extra operand so we don't match on cmpdi.
+; ELF64: cmpd {{[0-9]+}}
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  call void @foo()
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+