From e32ff4b28af4860505e06344383768ce832f615d Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 7 Sep 2018 14:40:06 +0000 Subject: [PATCH] [InstCombine] Do not fold scalar ops over select with vector condition. If OtherOpT or OtherOpF have scalar types and the condition is a vector, we would create an invalid select. Reviewers: spatel, john.brawn, mssimpso, craig.topper Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D51781 llvm-svn: 341666 --- .../Transforms/InstCombine/InstCombineSelect.cpp | 8 ++++++++ llvm/test/Transforms/InstCombine/select-gep.ll | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 3b79ea55a212..622b6eace5d1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -362,6 +362,14 @@ Instruction *InstCombiner::foldSelectOpOp(SelectInst &SI, Instruction *TI, return nullptr; } + // If the select condition is a vector, the operands of the original select's + // operands also must be vectors. This may not be the case for getelementptr + // for example. + if (SI.getCondition()->getType()->isVectorTy() && + (!OtherOpT->getType()->isVectorTy() || + !OtherOpF->getType()->isVectorTy())) + return nullptr; + // If we reach here, they do have operations in common. Value *NewSI = Builder.CreateSelect(SI.getCondition(), OtherOpT, OtherOpF, SI.getName() + ".v", &SI); diff --git a/llvm/test/Transforms/InstCombine/select-gep.ll b/llvm/test/Transforms/InstCombine/select-gep.ll index 90bbc4907b91..72166b69e9f8 100644 --- a/llvm/test/Transforms/InstCombine/select-gep.ll +++ b/llvm/test/Transforms/InstCombine/select-gep.ll @@ -136,3 +136,17 @@ define i32* @test4(i32* %p, i32* %q, i64 %x, i64 %y) { ret i32* %select } +; We cannot create a select with a vector condition but scalar operands. + +define <2 x i64*> @test5(i64* %p1, i64* %p2, <2 x i64> %idx, <2 x i1> %cc) { +; CHECK-LABEL: @test5( +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, i64* %p1, <2 x i64> %idx +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i64, i64* %p2, <2 x i64> %idx +; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> %cc, <2 x i64*> [[GEP1]], <2 x i64*> [[GEP2]] +; CHECK-NEXT: ret <2 x i64*> [[SELECT]] +; + %gep1 = getelementptr i64, i64* %p1, <2 x i64> %idx + %gep2 = getelementptr i64, i64* %p2, <2 x i64> %idx + %select = select <2 x i1> %cc, <2 x i64*> %gep1, <2 x i64*> %gep2 + ret <2 x i64*> %select +}