blob: 8a50409999627534b57c2f313bf158363fd58bc3 [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
David Neto118188e2018-08-24 11:27:54 -040015#include "llvm/IR/IRBuilder.h"
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040016#include "llvm/IR/Instructions.h"
David Neto118188e2018-08-24 11:27:54 -040017#include "llvm/IR/Module.h"
18#include "llvm/Pass.h"
19#include "llvm/Support/raw_ostream.h"
David Netodbb61f32017-09-29 15:50:36 -040020
Diego Novilloa4c44fa2019-04-11 10:56:15 -040021#include "Passes.h"
22
David Netodbb61f32017-09-29 15:50:36 -040023using namespace llvm;
24
25#define DEBUG_TYPE "splatselectcond"
26
27namespace {
28struct SplatSelectConditionPass : public ModulePass {
29 static char ID;
30 SplatSelectConditionPass() : ModulePass(ID) {}
31
32 bool runOnModule(Module &M) override;
33};
34} // namespace
35
36char SplatSelectConditionPass::ID = 0;
Diego Novilloa4c44fa2019-04-11 10:56:15 -040037INITIALIZE_PASS(SplatSelectConditionPass, "SplatSelectCond",
38 "Splat Select Condition Pass", false, false)
David Netodbb61f32017-09-29 15:50:36 -040039
40namespace clspv {
41llvm::ModulePass *createSplatSelectConditionPass() {
42 return new SplatSelectConditionPass();
43}
44} // namespace clspv
45
David Netodbb61f32017-09-29 15:50:36 -040046bool SplatSelectConditionPass::runOnModule(Module &M) {
47 bool Changed = false;
48
49 SmallVector<SelectInst *, 16> WorkList;
50 for (Function &F : M) {
51 for (BasicBlock &BB : F) {
52 for (Instruction &I : BB) {
53 if (SelectInst *sel = dyn_cast<SelectInst>(&I)) {
54 auto cond = sel->getCondition();
55 if (cond->getType()->isIntegerTy(1)) {
56 Type *valueTy = sel->getTrueValue()->getType();
57 if (valueTy->isVectorTy()) {
58 WorkList.push_back(sel);
59 }
60 }
61 }
62 }
63 }
64 }
65
66 if (WorkList.size() == 0)
67 return Changed;
68
69 IRBuilder<> Builder(WorkList.front());
70
71 for (SelectInst *sel : WorkList) {
72 Changed = true;
73 auto cond = sel->getCondition();
alan-baker5a8c3be2020-09-09 13:44:26 -040074 auto numElems = cast<VectorType>(sel->getTrueValue()->getType())
75 ->getElementCount()
76 .getKnownMinValue();
David Netodbb61f32017-09-29 15:50:36 -040077 Builder.SetInsertPoint(sel);
78 auto splat = Builder.CreateVectorSplat(numElems, cond);
79 sel->setCondition(splat);
80 }
81
82 return Changed;
83}