Skip to content

Commit

Permalink
[PowerPC] Enhance the fast selection of cmp instruction and clean up …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
wuzish committed Jan 25, 2019
1 parent 8de5abc commit 308a609
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 31 deletions.
15 changes: 12 additions & 3 deletions llvm/lib/Target/PowerPC/PPCFastISel.cpp
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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;
Expand Down
179 changes: 151 additions & 28 deletions llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
@@ -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

Expand All @@ -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

Expand All @@ -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

Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]+}}
Expand All @@ -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
}

0 comments on commit 308a609

Please sign in to comment.