Index: lib/Target/X86/X86FastISel.cpp =================================================================== --- lib/Target/X86/X86FastISel.cpp +++ lib/Target/X86/X86FastISel.cpp @@ -1651,6 +1651,7 @@ if (TestOpc) { unsigned OpReg = getRegForValue(TI->getOperand(0)); if (OpReg == 0) return false; + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TestOpc)) .addReg(OpReg).addImm(1); @@ -1688,8 +1689,20 @@ unsigned OpReg = getRegForValue(BI->getCondition()); if (OpReg == 0) return false; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) - .addReg(OpReg).addImm(1); + // In case OpReg is a K register, shift left and test it. + if (MRI.getRegClass(OpReg) == &X86::VK1RegClass) { + unsigned ResReg = createResultReg(&X86::VK1RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::KSHIFTLWri), + ResReg) + .addReg(OpReg) + .addImm(15); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::KTESTWrr)) + .addReg(ResReg) + .addReg(ResReg); + } else + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) + .addReg(OpReg) + .addImm(1); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JNE_1)) .addMBB(TrueMBB); finishCondBranch(BI->getParent(), TrueMBB, FalseMBB); @@ -2023,8 +2036,20 @@ return false; bool CondIsKill = hasTrivialKill(Cond); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) - .addReg(CondReg, getKillRegState(CondIsKill)).addImm(1); + // In case OpReg is a K register, shift left and test it. + if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) { + unsigned ResReg = createResultReg(&X86::VK1RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(X86::KSHIFTLWri), ResReg) + .addReg(CondReg) + .addImm(15); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::KTESTWrr)) + .addReg(ResReg) + .addReg(ResReg); + } else + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) + .addReg(CondReg, getKillRegState(CondIsKill)) + .addImm(1); } const Value *LHS = I->getOperand(1); @@ -2195,8 +2220,21 @@ if (CondReg == 0) return false; bool CondIsKill = hasTrivialKill(Cond); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) - .addReg(CondReg, getKillRegState(CondIsKill)).addImm(1); + + // In case OpReg is a K register, shift left and test it. + if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) { + unsigned ResReg = createResultReg(&X86::VK1RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(X86::KSHIFTLWri), ResReg) + .addReg(CondReg) + .addImm(15); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::KTESTWrr)) + .addReg(ResReg) + .addReg(ResReg); + } else + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri)) + .addReg(CondReg, getKillRegState(CondIsKill)) + .addImm(1); } const Value *LHS = I->getOperand(1); Index: test/CodeGen/X86/fast-isel-select-cmov.ll =================================================================== --- test/CodeGen/X86/fast-isel-select-cmov.ll +++ test/CodeGen/X86/fast-isel-select-cmov.ll @@ -1,13 +1,17 @@ -; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 | FileCheck %s +; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 | FileCheck %s --check-prefixes CHECK,NOAVX512 +; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 -mattr=+avx512f | FileCheck %s --check-prefixes CHECK,AVX512 ; Test conditional move for the supported types (i16, i32, and i32) and ; conditon input (argument or cmp). Currently i8 is not supported. define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroext %b) { ; CHECK-LABEL: select_cmov_i16 -; CHECK: testb $1, %dil -; CHECK-NEXT: cmovew %dx, %si -; CHECK-NEXT: movzwl %si, %eax +; NOAVX512: testb $1, %dil +; AVX512: kmovw %edi, %k0 +; AVX512-NEXT: kshiftlw $15, %k0, %k0 +; AVX512-NEXT: ktestw %k0, %k0 +; CHECK-NEXT: cmovew %dx, %si +; CHECK-NEXT: movzwl %si, %eax %1 = select i1 %cond, i16 %a, i16 %b ret i16 %1 } @@ -24,7 +28,10 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) { ; CHECK-LABEL: select_cmov_i32 -; CHECK: testb $1, %dil +; NOAVX512: testb $1, %dil +; AVX512: kmovw %edi, %k0 +; AVX512-NEXT: kshiftlw $15, %k0, %k0 +; AVX512-NEXT: ktestw %k0, %k0 ; CHECK-NEXT: cmovel %edx, %esi ; CHECK-NEXT: movl %esi, %eax %1 = select i1 %cond, i32 %a, i32 %b @@ -43,7 +50,10 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) { ; CHECK-LABEL: select_cmov_i64 -; CHECK: testb $1, %dil +; NOAVX512: testb $1, %dil +; AVX512: kmovw %edi, %k0 +; AVX512-NEXT: kshiftlw $15, %k0, %k0 +; AVX512-NEXT: ktestw %k0, %k0 ; CHECK-NEXT: cmoveq %rdx, %rsi ; CHECK-NEXT: movq %rsi, %rax %1 = select i1 %cond, i64 %a, i64 %b