From: Zi Xuan Wu Date: Fri, 25 Jan 2019 07:24:59 +0000 (+0000) Subject: [PowerPC] Enhance the fast selection of cmp instruction and clean up related asserts X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be71419bf023be9fd500ea5a7ea97fd8bf6a8dcf;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352174 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCFastISel.cpp b/lib/Target/PowerPC/PPCFastISel.cpp index 3f9a10752bd..a597c5ef6f6 100644 --- a/lib/Target/PowerPC/PPCFastISel.cpp +++ b/lib/Target/PowerPC/PPCFastISel.cpp @@ -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; diff --git a/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll b/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll index 004b82f09b8..df8d37d4d36 100644 --- a/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll +++ b/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 @@ -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 +} +