Index: llvm/lib/Target/PowerPC/PPCFastISel.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -874,7 +874,10 @@ 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: @@ -893,12 +896,18 @@ } } 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: @@ -915,7 +924,7 @@ CmpOpc = PPC::EFDCMPGT; break; } - } else if (isVSFRCRegClass(RC)) { + } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) { CmpOpc = PPC::XSCMPUDP; } else { CmpOpc = PPC::FCMPUD; Index: llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll =================================================================== --- llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll +++ 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 @@ -23,16 +27,41 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 +} +