mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +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:
parent
5c87dfd905
commit
287883a58b
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user