[llvm] r352174 - [PowerPC] Enhance the fast selection of cmp instruction and clean up related asserts

Zi Xuan Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 24 23:24:59 PST 2019


Author: wuzish
Date: Thu Jan 24 23:24:59 2019
New Revision: 352174

URL: http://llvm.org/viewvc/llvm-project?rev=352174&view=rev
Log:
[PowerPC] Enhance the fast selection of cmp instruction and clean up related asserts

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

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
    llvm/trunk/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=352174&r1=352173&r2=352174&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Thu Jan 24 23:24:59 2019
@@ -873,7 +873,10 @@ bool PPCFastISel::PPCEmitCmp(const Value
 
   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
         }
       } 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
             CmpOpc = PPC::EFDCMPGT;
             break;
         }
-      } else if (isVSFRCRegClass(RC)) {
+      } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
         CmpOpc = PPC::XSCMPUDP;
       } else {
         CmpOpc = PPC::FCMPUD;

Modified: llvm/trunk/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll?rev=352174&r1=352173&r2=352174&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll Thu Jan 24 23:24:59 2019
@@ -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:
   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:
 
 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:
 
 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:
 
 define void @t4(i8 signext %a) nounwind {
 entry:
-; ELF64: t4
+; ELF64-LABEL: @t4
   %cmp = icmp eq i8 %a, -1
 ; ELF64: extsb
 ; ELF64: cmpwi
@@ -100,7 +160,7 @@ if.end:
 
 define void @t5(i8 zeroext %a) nounwind {
 entry:
-; ELF64: t5
+; ELF64-LABEL: @t5
   %cmp = icmp eq i8 %a, 1
 ; ELF64: extsb
 ; ELF64: cmpwi
@@ -114,9 +174,25 @@ if.end:
   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:
-; ELF64: t6
+; ELF64-LABEL: @t6
   %cmp = icmp eq i16 %a, -1
 ; ELF64: extsh
 ; ELF64: cmpwi
@@ -132,7 +208,7 @@ if.end:
 
 define void @t7(i16 zeroext %a) nounwind {
 entry:
-; ELF64: t7
+; ELF64-LABEL: @t7
   %cmp = icmp eq i16 %a, 1
 ; ELF64: extsh
 ; ELF64: cmpwi
@@ -146,9 +222,25 @@ if.end:
   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:
-; ELF64: t8
+; 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:
 
 define void @t9(i32 %a) nounwind {
 entry:
-; ELF64: t9
+; 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:
 
 define void @t10(i32 %a) nounwind {
 entry:
-; ELF64: t10
+; 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:
 
 define void @t11(i32 %a) nounwind {
 entry:
-; ELF64: t11
+; 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:
   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:
-; ELF64: t12
+; ELF64-LABEL: @t12
   %cmp = icmp ugt i8 %a, -113
 ; ELF64: clrlwi
 ; ELF64: cmplwi
@@ -224,7 +331,7 @@ if.end:
 
 define void @t13() nounwind ssp {
 entry:
-; ELF64: t13
+; ELF64-LABEL: @t13
   %cmp = icmp slt i32 -123, -2147483648
 ; ELF64: li
 ; ELF64: lis
@@ -240,7 +347,7 @@ if.end:
 
 define void @t14(i64 %a) nounwind {
 entry:
-; ELF64: t14
+; 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:
 
 define void @t15(i64 %a) nounwind {
 entry:
-; ELF64: t15
+; 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:
 
 define void @t16(i64 %a) nounwind {
 entry:
-; ELF64: t16
+; ELF64-LABEL: @t16
   %cmp = icmp eq i64 %a, 384
 ; ELF64: cmpdi
   br i1 %cmp, label %if.then, label %if.end
@@ -285,11 +392,27 @@ if.end:
 
 define void @t17(i64 %a) nounwind {
 entry:
-; ELF64: t17
+; ELF64-LABEL: @t17
   %cmp = icmp eq i64 %a, 32768
 ; 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
+}
+
+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()




More information about the llvm-commits mailing list