From 7b4cd228aa920b62a4bc1c04e4055f069dc11285 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Thu, 27 Sep 2012 08:33:56 +0000 Subject: [PATCH] Prefer shuffles to selects. Backends love shuffles! llvm-svn: 164763 --- .../Transforms/InstCombine/InstCombineSelect.cpp | 20 ++++++++++++- .../Transforms/InstCombine/vec_demanded_elts.ll | 2 +- llvm/test/Transforms/InstCombine/vec_shuffle.ll | 35 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 291e800..70483ce 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -903,7 +903,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return &SI; } - if (VectorType* VecTy = dyn_cast(SI.getType())) { + if (VectorType *VecTy = dyn_cast(SI.getType())) { unsigned VWidth = VecTy->getNumElements(); APInt UndefElts(VWidth, 0); APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); @@ -912,6 +912,24 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return ReplaceInstUsesWith(SI, V); return &SI; } + + if (ConstantVector *CV = dyn_cast(CondVal)) { + // Form a shufflevector instruction. + SmallVector Mask(VWidth); + Type *Int32Ty = Type::getInt32Ty(CV->getContext()); + for (unsigned i = 0; i != VWidth; ++i) { + Constant *Elem = cast(CV->getOperand(i)); + if (ConstantInt *E = dyn_cast(Elem)) + Mask[i] = ConstantInt::get(Int32Ty, i + (E->isZero() ? VWidth : 0)); + else if (isa(Elem)) + Mask[i] = UndefValue::get(Int32Ty); + else + return 0; + } + Constant *MaskVal = ConstantVector::get(Mask); + Value *V = Builder->CreateShuffleVector(TrueVal, FalseVal, MaskVal); + return ReplaceInstUsesWith(SI, V); + } } return 0; diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll index 0019a57..2d90750 100644 --- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -196,7 +196,7 @@ define <4 x float> @test_select(float %f, float %g) { ; CHECK-NOT: insertelement ; CHECK: %a3 = insertelement <4 x float> %a0, float 3.000000e+00, i32 3 ; CHECK-NOT: insertelement -; CHECK: %ret = select <4 x i1> , <4 x float> %a3, <4 x float> +; CHECK: shufflevector <4 x float> %a3, <4 x float> , <4 x i32> %a0 = insertelement <4 x float> undef, float %f, i32 0 %a1 = insertelement <4 x float> %a0, float 1.000000e+00, i32 1 %a2 = insertelement <4 x float> %a1, float 2.000000e+00, i32 2 diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index 8f78c2e..a7f9fcf 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -153,3 +153,38 @@ define <8 x i8> @test12a(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind { ret <8 x i8> %tmp3 } +; We should form a shuffle out of a select with constant condition. +define <4 x i16> @test13a(<4 x i16> %lhs, <4 x i16> %rhs) { +; CHECK: @test13a +; CHECK-NEXT: shufflevector <4 x i16> %lhs, <4 x i16> %rhs, <4 x i32> +; CHECK-NEXT: ret + %A = select <4 x i1> , + <4 x i16> %lhs, <4 x i16> %rhs + ret <4 x i16> %A +} + +define <4 x i16> @test13b(<4 x i16> %lhs, <4 x i16> %rhs) { +; CHECK: @test13b +; CHECK-NEXT: ret <4 x i16> %lhs + %A = select <4 x i1> , + <4 x i16> %lhs, <4 x i16> %rhs + ret <4 x i16> %A +} + +define <4 x i16> @test13c(<4 x i16> %lhs, <4 x i16> %rhs) { +; CHECK: @test13c +; CHECK-NEXT: shufflevector <4 x i16> %lhs, <4 x i16> %rhs, <4 x i32> +; CHECK-NEXT: ret + %A = select <4 x i1> , + <4 x i16> %lhs, <4 x i16> %rhs + ret <4 x i16> %A +} + +define <4 x i16> @test13d(<4 x i16> %lhs, <4 x i16> %rhs) { +; CHECK: @test13d +; CHECK: select +; CHECK-NEXT: ret + %A = select <4 x i1> (<4 x i16>, <4 x i16>)* @test13a, <4 x i16>(<4 x i16>, <4 x i16>)* @test13b), i1 true, i1 false>, + <4 x i16> %lhs, <4 x i16> %rhs + ret <4 x i16> %A +} -- 2.7.4