Index: lib/Target/X86/X86InstrCompiler.td =================================================================== --- lib/Target/X86/X86InstrCompiler.td +++ lib/Target/X86/X86InstrCompiler.td @@ -1289,15 +1289,13 @@ // Any instruction that defines a 32-bit result leaves the high half of the // register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may -// be copying from a truncate. And x86's cmov doesn't do anything if the -// condition is false. But any other 32-bit operation will zero-extend +// be copying from a truncate. Any other 32-bit operation will zero-extend // up to 64 bits. def def32 : PatLeaf<(i32 GR32:$src), [{ return N->getOpcode() != ISD::TRUNCATE && N->getOpcode() != TargetOpcode::EXTRACT_SUBREG && N->getOpcode() != ISD::CopyFromReg && - N->getOpcode() != ISD::AssertSext && - N->getOpcode() != X86ISD::CMOV; + N->getOpcode() != ISD::AssertSext; }]>; // In the case of a 32-bit def that is known to implicitly zero-extend, Index: test/CodeGen/X86/cmov.ll =================================================================== --- test/CodeGen/X86/cmov.ll +++ test/CodeGen/X86/cmov.ll @@ -33,16 +33,17 @@ } -; x86's 32-bit cmov doesn't clobber the high 32 bits of the destination -; if the condition is false. An explicit zero-extend (movl) is needed -; after the cmov. +; x86's 32-bit cmov zeroes the high 32 bits of the destination. Make +; sure CodeGen takes advantage of that to avoid an unnecessary +; zero-extend (movl) after the cmov. declare void @bar(i64) nounwind define void @test3(i64 %a, i64 %b, i1 %p) nounwind { ; CHECK-LABEL: test3: ; CHECK: cmov{{n?}}el %[[R1:e..]], %[[R2:e..]] -; CHECK-NEXT: movl %[[R2]], %{{e..}} +; CHECK-NOT: movl +; CHECK: call %c = trunc i64 %a to i32 %d = trunc i64 %b to i32