1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[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

llvm-svn: 352174
This commit is contained in:
Zi Xuan Wu 2019-01-25 07:24:59 +00:00
parent 5c87dfd905
commit 287883a58b
2 changed files with 163 additions and 31 deletions

View 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;

View 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:
; ELF64: t4
; 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:
; ELF64: t5
; 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:
; ELF64: t6
; 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:
; ELF64: t7
; 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:
; 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: ; preds = %if.then, %entry
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: ; preds = %if.then, %entry
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: ; preds = %if.then, %entry
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: ; 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:
; ELF64: t12
; 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:
; ELF64: t13
; 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:
; 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: ; preds = %if.then, %entry
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: ; preds = %if.then, %entry
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,7 +392,7 @@ if.end: ; preds = %if.then, %entry
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]+}}
@ -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
}