blob: 62f6ac0d4fa54a9ddc90aac792c86ee51f10b100 [file] [log] [blame]
David Netodbb61f32017-09-29 15:50:36 -04001// Copyright 2017 The Clspv Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <llvm/IR/Instructions.h>
16#include <llvm/IR/IRBuilder.h>
17#include <llvm/IR/Module.h>
18#include <llvm/Pass.h>
19#include <llvm/Support/raw_ostream.h>
20
21using namespace llvm;
22
23#define DEBUG_TYPE "splatselectcond"
24
25namespace {
26struct SplatSelectConditionPass : public ModulePass {
27 static char ID;
28 SplatSelectConditionPass() : ModulePass(ID) {}
29
30 bool runOnModule(Module &M) override;
31};
32} // namespace
33
34char SplatSelectConditionPass::ID = 0;
35static RegisterPass<SplatSelectConditionPass>
36 X("SplatSelectCond", "Splat Select Condition Pass");
37
38namespace clspv {
39llvm::ModulePass *createSplatSelectConditionPass() {
40 return new SplatSelectConditionPass();
41}
42} // namespace clspv
43
44
45bool SplatSelectConditionPass::runOnModule(Module &M) {
46 bool Changed = false;
47
48 SmallVector<SelectInst *, 16> WorkList;
49 for (Function &F : M) {
50 for (BasicBlock &BB : F) {
51 for (Instruction &I : BB) {
52 if (SelectInst *sel = dyn_cast<SelectInst>(&I)) {
53 auto cond = sel->getCondition();
54 if (cond->getType()->isIntegerTy(1)) {
55 Type *valueTy = sel->getTrueValue()->getType();
56 if (valueTy->isVectorTy()) {
57 WorkList.push_back(sel);
58 }
59 }
60 }
61 }
62 }
63 }
64
65 if (WorkList.size() == 0)
66 return Changed;
67
68 IRBuilder<> Builder(WorkList.front());
69
70 for (SelectInst *sel : WorkList) {
71 Changed = true;
72 auto cond = sel->getCondition();
73 auto numElems = sel->getTrueValue()->getType()->getVectorNumElements();
74 Builder.SetInsertPoint(sel);
75 auto splat = Builder.CreateVectorSplat(numElems, cond);
76 sel->setCondition(splat);
77 }
78
79 return Changed;
80}