From: Elena Demikhovsky Date: Mon, 28 Mar 2016 07:47:58 +0000 (+0000) Subject: AVX-512: Fixed ICMP instruction selection for i1 operands X-Git-Tag: llvmorg-3.9.0-rc1~10773 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=83f0647d85e37806df88546063bef26e6a9bb01f;p=platform%2Fupstream%2Fllvm.git AVX-512: Fixed ICMP instruction selection for i1 operands ICMP instruction selection fails on SKX and KNL for i1 operand. I use XOR to resolve: (A == B) is equivalent to (A xor B) == 0 Differential Revision: http://reviews.llvm.org/D18511 llvm-svn: 264566 --- diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a06faba..98c020c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -15523,11 +15523,15 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { return SetCC; } } - if ((Op0.getValueType() == MVT::i1) && isOneConstant(Op1) && - (CC == ISD::SETEQ || CC == ISD::SETNE)) { - - ISD::CondCode NewCC = ISD::getSetCCInverse(CC, true); - return DAG.getSetCC(dl, VT, Op0, DAG.getConstant(0, dl, MVT::i1), NewCC); + if (Op0.getValueType() == MVT::i1 && (CC == ISD::SETEQ || CC == ISD::SETNE)) { + if (isOneConstant(Op1)) { + ISD::CondCode NewCC = ISD::getSetCCInverse(CC, true); + return DAG.getSetCC(dl, VT, Op0, DAG.getConstant(0, dl, MVT::i1), NewCC); + } + if (!isNullConstant(Op1)) { + SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i1, Op0, Op1); + return DAG.getSetCC(dl, VT, Xor, DAG.getConstant(0, dl, MVT::i1), CC); + } } bool isFP = Op1.getSimpleValueType().isFloatingPoint(); diff --git a/llvm/test/CodeGen/X86/avx512-cmp.ll b/llvm/test/CodeGen/X86/avx512-cmp.ll index 6e0d185..68989b1 100644 --- a/llvm/test/CodeGen/X86/avx512-cmp.ll +++ b/llvm/test/CodeGen/X86/avx512-cmp.ll @@ -1,8 +1,19 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl --show-mc-encoding | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl | FileCheck %s --check-prefix=ALL --check-prefix=KNL +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=skx | FileCheck %s --check-prefix=ALL --check-prefix=SKX -; CHECK-LABEL: test1 -; CHECK: vucomisd {{.*}}encoding: [0x62 define double @test1(double %a, double %b) nounwind { +; ALL-LABEL: test1: +; ALL: ## BB#0: +; ALL-NEXT: vucomisd %xmm1, %xmm0 +; ALL-NEXT: jne LBB0_1 +; ALL-NEXT: jnp LBB0_2 +; ALL-NEXT: LBB0_1: ## %l1 +; ALL-NEXT: vsubsd %xmm1, %xmm0, %xmm0 +; ALL-NEXT: retq +; ALL-NEXT: LBB0_2: ## %l2 +; ALL-NEXT: vaddsd %xmm1, %xmm0, %xmm0 +; ALL-NEXT: retq %tobool = fcmp une double %a, %b br i1 %tobool, label %l1, label %l2 @@ -14,9 +25,17 @@ l2: ret double %c1 } -; CHECK-LABEL: test2 -; CHECK: vucomiss {{.*}}encoding: [0x62 define float @test2(float %a, float %b) nounwind { +; ALL-LABEL: test2: +; ALL: ## BB#0: +; ALL-NEXT: vucomiss %xmm0, %xmm1 +; ALL-NEXT: jbe LBB1_2 +; ALL-NEXT: ## BB#1: ## %l1 +; ALL-NEXT: vsubss %xmm1, %xmm0, %xmm0 +; ALL-NEXT: retq +; ALL-NEXT: LBB1_2: ## %l2 +; ALL-NEXT: vaddss %xmm1, %xmm0, %xmm0 +; ALL-NEXT: retq %tobool = fcmp olt float %a, %b br i1 %tobool, label %l1, label %l2 @@ -29,18 +48,35 @@ l2: } ; FIXME: Can use vcmpeqss and extract from the mask here in AVX512. -; CHECK-LABEL: test3 -; CHECK: vucomiss {{.*}}encoding: [0x62 define i32 @test3(float %a, float %b) { +; ALL-LABEL: test3: +; ALL: ## BB#0: +; ALL-NEXT: vucomiss %xmm1, %xmm0 +; ALL-NEXT: setnp %al +; ALL-NEXT: sete %cl +; ALL-NEXT: andb %al, %cl +; ALL-NEXT: movzbl %cl, %eax +; ALL-NEXT: retq %cmp10.i = fcmp oeq float %a, %b %conv11.i = zext i1 %cmp10.i to i32 ret i32 %conv11.i } -; CHECK-LABEL: test5 -; CHECK: ret define float @test5(float %p) #0 { +; ALL-LABEL: test5: +; ALL: ## BB#0: ## %entry +; ALL-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; ALL-NEXT: vucomiss %xmm1, %xmm0 +; ALL-NEXT: jne LBB3_1 +; ALL-NEXT: jnp LBB3_2 +; ALL-NEXT: LBB3_1: ## %if.end +; ALL-NEXT: seta %al +; ALL-NEXT: movzbl %al, %eax +; ALL-NEXT: leaq {{.*}}(%rip), %rcx +; ALL-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; ALL-NEXT: LBB3_2: ## %return +; ALL-NEXT: retq entry: %cmp = fcmp oeq float %p, 0.000000e+00 br i1 %cmp, label %return, label %if.end @@ -55,21 +91,25 @@ return: ; preds = %if.end, %entry ret float %retval.0 } -; CHECK-LABEL: test6 -; CHECK: cmpl -; CHECK-NOT: kmov -; CHECK: ret define i32 @test6(i32 %a, i32 %b) { +; ALL-LABEL: test6: +; ALL: ## BB#0: +; ALL-NEXT: cmpl %esi, %edi +; ALL-NEXT: sete %al +; ALL-NEXT: movzbl %al, %eax +; ALL-NEXT: retq %cmp = icmp eq i32 %a, %b %res = zext i1 %cmp to i32 ret i32 %res } -; CHECK-LABEL: test7 -; CHECK: vucomisd -; CHECK-NOT: kmov -; CHECK: ret define i32 @test7(double %x, double %y) #2 { +; ALL-LABEL: test7: +; ALL: ## BB#0: ## %entry +; ALL-NEXT: vucomisd %xmm1, %xmm0 +; ALL-NEXT: setne %al +; ALL-NEXT: movzbl %al, %eax +; ALL-NEXT: retq entry: %0 = fcmp one double %x, %y %or = zext i1 %0 to i32 @@ -77,6 +117,16 @@ entry: } define i32 @test8(i32 %a1, i32 %a2, i32 %a3) { +; ALL-LABEL: test8: +; ALL: ## BB#0: +; ALL-NEXT: testl %edx, %edx +; ALL-NEXT: movl $1, %eax +; ALL-NEXT: cmovel %eax, %edx +; ALL-NEXT: cmpl $-2147483648, %esi ## imm = 0xFFFFFFFF80000000 +; ALL-NEXT: cmovnel %edx, %eax +; ALL-NEXT: cmpl $-1, %edi +; ALL-NEXT: cmovnel %edx, %eax +; ALL-NEXT: retq %tmp1 = icmp eq i32 %a1, -1 %tmp2 = icmp eq i32 %a2, -2147483648 %tmp3 = and i1 %tmp1, %tmp2 @@ -86,11 +136,17 @@ define i32 @test8(i32 %a1, i32 %a2, i32 %a3) { ret i32 %res } -; CHECK-LABEL: test9 -; CHECK: testb -; CHECK-NOT: kmov -; CHECK: ret define i32 @test9(i64 %a) { +; ALL-LABEL: test9: +; ALL: ## BB#0: +; ALL-NEXT: testb $1, %dil +; ALL-NEXT: jne LBB7_2 +; ALL-NEXT: ## BB#1: ## %A +; ALL-NEXT: movl $6, %eax +; ALL-NEXT: retq +; ALL-NEXT: LBB7_2: ## %B +; ALL-NEXT: movl $7, %eax +; ALL-NEXT: retq %b = and i64 %a, 1 %cmp10.i = icmp eq i64 %b, 0 br i1 %cmp10.i, label %A, label %B @@ -99,3 +155,37 @@ A: B: ret i32 7 } + +define i32 @test10(i64 %b, i64 %c, i1 %d) { +; ALL-LABEL: test10: +; ALL: ## BB#0: +; ALL-NEXT: andl $1, %edx +; ALL-NEXT: kmovw %edx, %k0 +; ALL-NEXT: cmpq %rsi, %rdi +; ALL-NEXT: sete %al +; ALL-NEXT: andl $1, %eax +; ALL-NEXT: kmovw %eax, %k1 +; ALL-NEXT: korw %k1, %k0, %k1 +; ALL-NEXT: kxorw %k1, %k0, %k0 +; ALL-NEXT: kmovw %k0, %eax +; ALL-NEXT: andl $1, %eax +; ALL-NEXT: testb %al, %al +; ALL-NEXT: je LBB8_1 +; ALL-NEXT: ## BB#2: ## %if.end.i +; ALL-NEXT: movl $6, %eax +; ALL-NEXT: retq +; ALL-NEXT: LBB8_1: ## %if.then.i +; ALL-NEXT: movl $5, %eax +; ALL-NEXT: retq + + %cmp8.i = icmp eq i64 %b, %c + %or1 = or i1 %d, %cmp8.i + %xor1 = xor i1 %d, %or1 + br i1 %xor1, label %if.end.i, label %if.then.i + +if.then.i: + ret i32 5 + +if.end.i: + ret i32 6 +}