diff options
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 7 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/vselect-avx.ll | 27 |
2 files changed, 33 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a8afe816d90..543a2fdc99f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -22598,7 +22598,12 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::TargetLoweringOpt TLO(DAG, DCI.isBeforeLegalize(), DCI.isBeforeLegalizeOps()); if (TLO.ShrinkDemandedConstant(Cond, DemandedMask) || - TLI.SimplifyDemandedBits(Cond, DemandedMask, KnownZero, KnownOne, TLO)) + (TLI.SimplifyDemandedBits(Cond, DemandedMask, KnownZero, KnownOne, + TLO) && + // Don't optimize vector of constants. Those are handled by + // the generic code and all the bits must be properly set for + // the generic optimizer. + !ISD::isBuildVectorOfConstantSDNodes(TLO.New.getNode()))) DCI.CommitTargetLoweringOpt(TLO); } diff --git a/llvm/test/CodeGen/X86/vselect-avx.ll b/llvm/test/CodeGen/X86/vselect-avx.ll new file mode 100644 index 00000000000..2d7ccf39d38 --- /dev/null +++ b/llvm/test/CodeGen/X86/vselect-avx.ll @@ -0,0 +1,27 @@ +; RUN: llc %s -o - -mattr=+avx | FileCheck %s +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx" + +; For this test we used to optimize the <i1 true, i1 false, i1 false, i1 true> +; mask into <i32 2147483648, i32 0, i32 0, i32 2147483648> because we thought +; we would lower that into a blend where only the high bit is relevant. +; However, since the whole mask is constant, this is simplified incorrectly +; by the generic code, because it was expecting -1 in place of 2147483648. +; +; The problem does not occur without AVX, because vselect of v4i32 is not legal +; nor custom. +; +; <rdar://problem/18675020> + +; CHECK-LABEL: test: +; CHECK: vmovdqa {{.*#+}} xmm1 = [65533,124,125,14807] +; CHECK: vmovdqa {{.*#+}} xmm1 = [65535,0,0,65535] +; CHECK: ret +define void @test(<4 x i16>* %a, <4 x i16>* %b) { +body: + %predphi = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i16> <i16 -3, i16 545, i16 4385, i16 14807>, <4 x i16> <i16 123, i16 124, i16 125, i16 127> + %predphi42 = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>, <4 x i16> zeroinitializer + store <4 x i16> %predphi, <4 x i16>* %a, align 8 + store <4 x i16> %predphi42, <4 x i16>* %b, align 8 + ret void +} |