annotate lib/CodeGen/ScalarizeMaskedMemIntrin.cpp @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents 803732b1fca8
children c2174574ed3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===- ScalarizeMaskedMemIntrin.cpp - Scalarize unsupported masked mem ----===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 // instrinsics
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
3 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
4 // The LLVM Compiler Infrastructure
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
5 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 // This file is distributed under the University of Illinois Open Source
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 // License. See LICENSE.TXT for details.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 // This pass replaces masked memory intrinsics - when unsupported by the target
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12 // - with a chain of basic blocks, that deal with the elements one-by-one if the
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 // appropriate mask bit is set.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17 #include "llvm/ADT/Twine.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18 #include "llvm/Analysis/TargetTransformInfo.h"
134
3a76565eade5 update 5.0.1
mir3636
parents: 121
diff changeset
19 #include "llvm/CodeGen/TargetSubtargetInfo.h"
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 #include "llvm/IR/BasicBlock.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21 #include "llvm/IR/Constant.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 #include "llvm/IR/Constants.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23 #include "llvm/IR/DerivedTypes.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 #include "llvm/IR/Function.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25 #include "llvm/IR/IRBuilder.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26 #include "llvm/IR/InstrTypes.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27 #include "llvm/IR/Instruction.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28 #include "llvm/IR/Instructions.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29 #include "llvm/IR/IntrinsicInst.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30 #include "llvm/IR/Intrinsics.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31 #include "llvm/IR/Type.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 #include "llvm/IR/Value.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33 #include "llvm/Pass.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 #include "llvm/Support/Casting.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35 #include <algorithm>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36 #include <cassert>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38 using namespace llvm;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40 #define DEBUG_TYPE "scalarize-masked-mem-intrin"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42 namespace {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44 class ScalarizeMaskedMemIntrin : public FunctionPass {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45 const TargetTransformInfo *TTI = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47 public:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48 static char ID; // Pass identification, replacement for typeid
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 explicit ScalarizeMaskedMemIntrin() : FunctionPass(ID) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 initializeScalarizeMaskedMemIntrinPass(*PassRegistry::getPassRegistry());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54 bool runOnFunction(Function &F) override;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56 StringRef getPassName() const override {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57 return "Scalarize Masked Memory Intrinsics";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60 void getAnalysisUsage(AnalysisUsage &AU) const override {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61 AU.addRequired<TargetTransformInfoWrapperPass>();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64 private:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65 bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66 bool optimizeCallInst(CallInst *CI, bool &ModifiedDT);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
68
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
69 } // end anonymous namespace
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 char ScalarizeMaskedMemIntrin::ID = 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 INITIALIZE_PASS(ScalarizeMaskedMemIntrin, DEBUG_TYPE,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74 "Scalarize unsupported masked memory intrinsics", false, false)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
76 FunctionPass *llvm::createScalarizeMaskedMemIntrinPass() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
77 return new ScalarizeMaskedMemIntrin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 // Translate a masked load intrinsic like
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 // <16 x i32 > @llvm.masked.load( <16 x i32>* %addr, i32 align,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
82 // <16 x i1> %mask, <16 x i32> %passthru)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
83 // to a chain of basic blocks, with loading element one-by-one if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84 // the appropriate mask bit is set
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86 // %1 = bitcast i8* %addr to i32*
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 // %2 = extractelement <16 x i1> %mask, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88 // %3 = icmp eq i1 %2, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89 // br i1 %3, label %cond.load, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91 // cond.load: ; preds = %0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 // %4 = getelementptr i32* %1, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 // %5 = load i32* %4
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94 // %6 = insertelement <16 x i32> undef, i32 %5, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 // br label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97 // else: ; preds = %0, %cond.load
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98 // %res.phi.else = phi <16 x i32> [ %6, %cond.load ], [ undef, %0 ]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99 // %7 = extractelement <16 x i1> %mask, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100 // %8 = icmp eq i1 %7, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101 // br i1 %8, label %cond.load1, label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103 // cond.load1: ; preds = %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 // %9 = getelementptr i32* %1, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105 // %10 = load i32* %9
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106 // %11 = insertelement <16 x i32> %res.phi.else, i32 %10, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 // br label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109 // else2: ; preds = %else, %cond.load1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 // %12 = extractelement <16 x i1> %mask, i32 2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112 // %13 = icmp eq i1 %12, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113 // br i1 %13, label %cond.load4, label %else5
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 static void scalarizeMaskedLoad(CallInst *CI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
116 Value *Ptr = CI->getArgOperand(0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
117 Value *Alignment = CI->getArgOperand(1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118 Value *Mask = CI->getArgOperand(2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 Value *Src0 = CI->getArgOperand(3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
120
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121 unsigned AlignVal = cast<ConstantInt>(Alignment)->getZExtValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 VectorType *VecType = dyn_cast<VectorType>(CI->getType());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
123 assert(VecType && "Unexpected return type of masked load intrinsic");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
124
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
125 Type *EltTy = CI->getType()->getVectorElementType();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
126
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
127 IRBuilder<> Builder(CI->getContext());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
128 Instruction *InsertPt = CI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
129 BasicBlock *IfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130 BasicBlock *CondBlock = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 BasicBlock *PrevIfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
132
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136 // Short-cut if the mask is all-true.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137 bool IsAllOnesMask =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 if (IsAllOnesMask) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141 Value *NewI = Builder.CreateAlignedLoad(Ptr, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 CI->replaceAllUsesWith(NewI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147 // Adjust alignment for the scalar instruction.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
148 AlignVal = std::min(AlignVal, VecType->getScalarSizeInBits() / 8);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
149 // Bitcast %addr fron i8* to EltTy*
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
150 Type *NewPtrType =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
151 EltTy->getPointerTo(cast<PointerType>(Ptr->getType())->getAddressSpace());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152 Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
153 unsigned VectorWidth = VecType->getNumElements();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
154
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
155 Value *UndefVal = UndefValue::get(VecType);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
156
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
157 // The result vector
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
158 Value *VResult = UndefVal;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
159
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
160 if (isa<ConstantVector>(Mask)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
161 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
162 if (cast<ConstantVector>(Mask)->getOperand(Idx)->isNullValue())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
163 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
164 Value *Gep =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
165 Builder.CreateInBoundsGEP(EltTy, FirstEltPtr, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
166 LoadInst *Load = Builder.CreateAlignedLoad(Gep, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
167 VResult =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
168 Builder.CreateInsertElement(VResult, Load, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
169 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
170 Value *NewI = Builder.CreateSelect(Mask, VResult, Src0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
171 CI->replaceAllUsesWith(NewI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
172 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
173 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
174 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
175
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
176 PHINode *Phi = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
177 Value *PrevPhi = UndefVal;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
178
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
179 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
180 // Fill the "else" block, created in the previous iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
181 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
182 // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
183 // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
184 // %to_load = icmp eq i1 %mask_1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
185 // br i1 %to_load, label %cond.load, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
186 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
187 if (Idx > 0) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
188 Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
189 Phi->addIncoming(VResult, CondBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
190 Phi->addIncoming(PrevPhi, PrevIfBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
191 PrevPhi = Phi;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
192 VResult = Phi;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
193 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
194
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
195 Value *Predicate =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
196 Builder.CreateExtractElement(Mask, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
197 Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_EQ, Predicate,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
198 ConstantInt::get(Predicate->getType(), 1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
199
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
200 // Create "cond" block
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
201 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
202 // %EltAddr = getelementptr i32* %1, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
203 // %Elt = load i32* %EltAddr
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
204 // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
205 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
206 CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.load");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
207 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
208
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
209 Value *Gep =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
210 Builder.CreateInBoundsGEP(EltTy, FirstEltPtr, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
211 LoadInst *Load = Builder.CreateAlignedLoad(Gep, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
212 VResult = Builder.CreateInsertElement(VResult, Load, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
213
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
214 // Create "else" block, fill it in the next iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
215 BasicBlock *NewIfBlock =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
216 CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
217 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
218 Instruction *OldBr = IfBlock->getTerminator();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
219 BranchInst::Create(CondBlock, NewIfBlock, Cmp, OldBr);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
220 OldBr->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
221 PrevIfBlock = IfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
222 IfBlock = NewIfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
223 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
224
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
225 Phi = Builder.CreatePHI(VecType, 2, "res.phi.select");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
226 Phi->addIncoming(VResult, CondBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
227 Phi->addIncoming(PrevPhi, PrevIfBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
228 Value *NewI = Builder.CreateSelect(Mask, Phi, Src0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
229 CI->replaceAllUsesWith(NewI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
230 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
231 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
232
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
233 // Translate a masked store intrinsic, like
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
234 // void @llvm.masked.store(<16 x i32> %src, <16 x i32>* %addr, i32 align,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
235 // <16 x i1> %mask)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
236 // to a chain of basic blocks, that stores element one-by-one if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
237 // the appropriate mask bit is set
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
238 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
239 // %1 = bitcast i8* %addr to i32*
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
240 // %2 = extractelement <16 x i1> %mask, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
241 // %3 = icmp eq i1 %2, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
242 // br i1 %3, label %cond.store, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
243 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
244 // cond.store: ; preds = %0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
245 // %4 = extractelement <16 x i32> %val, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
246 // %5 = getelementptr i32* %1, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
247 // store i32 %4, i32* %5
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
248 // br label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
249 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
250 // else: ; preds = %0, %cond.store
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
251 // %6 = extractelement <16 x i1> %mask, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
252 // %7 = icmp eq i1 %6, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
253 // br i1 %7, label %cond.store1, label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
254 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
255 // cond.store1: ; preds = %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
256 // %8 = extractelement <16 x i32> %val, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
257 // %9 = getelementptr i32* %1, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
258 // store i32 %8, i32* %9
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
259 // br label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
260 // . . .
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
261 static void scalarizeMaskedStore(CallInst *CI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
262 Value *Src = CI->getArgOperand(0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
263 Value *Ptr = CI->getArgOperand(1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
264 Value *Alignment = CI->getArgOperand(2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
265 Value *Mask = CI->getArgOperand(3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
266
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
267 unsigned AlignVal = cast<ConstantInt>(Alignment)->getZExtValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
268 VectorType *VecType = dyn_cast<VectorType>(Src->getType());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
269 assert(VecType && "Unexpected data type in masked store intrinsic");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
270
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
271 Type *EltTy = VecType->getElementType();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
272
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
273 IRBuilder<> Builder(CI->getContext());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
274 Instruction *InsertPt = CI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
275 BasicBlock *IfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
276 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
277 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
278
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
279 // Short-cut if the mask is all-true.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
280 bool IsAllOnesMask =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
281 isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
282
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
283 if (IsAllOnesMask) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
284 Builder.CreateAlignedStore(Src, Ptr, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
285 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
286 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
287 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
288
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
289 // Adjust alignment for the scalar instruction.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
290 AlignVal = std::max(AlignVal, VecType->getScalarSizeInBits() / 8);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
291 // Bitcast %addr fron i8* to EltTy*
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
292 Type *NewPtrType =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
293 EltTy->getPointerTo(cast<PointerType>(Ptr->getType())->getAddressSpace());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
294 Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
295 unsigned VectorWidth = VecType->getNumElements();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
296
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
297 if (isa<ConstantVector>(Mask)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
298 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
299 if (cast<ConstantVector>(Mask)->getOperand(Idx)->isNullValue())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
300 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
301 Value *OneElt = Builder.CreateExtractElement(Src, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
302 Value *Gep =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
303 Builder.CreateInBoundsGEP(EltTy, FirstEltPtr, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
304 Builder.CreateAlignedStore(OneElt, Gep, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
305 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
306 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
307 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
308 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
309
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
310 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
311 // Fill the "else" block, created in the previous iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
312 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
313 // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
314 // %to_store = icmp eq i1 %mask_1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
315 // br i1 %to_store, label %cond.store, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
316 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
317 Value *Predicate =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
318 Builder.CreateExtractElement(Mask, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
319 Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_EQ, Predicate,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
320 ConstantInt::get(Predicate->getType(), 1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
321
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
322 // Create "cond" block
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
323 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
324 // %OneElt = extractelement <16 x i32> %Src, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
325 // %EltAddr = getelementptr i32* %1, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
326 // %store i32 %OneElt, i32* %EltAddr
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
327 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
328 BasicBlock *CondBlock =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
329 IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.store");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
330 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
331
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
332 Value *OneElt = Builder.CreateExtractElement(Src, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
333 Value *Gep =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
334 Builder.CreateInBoundsGEP(EltTy, FirstEltPtr, Builder.getInt32(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
335 Builder.CreateAlignedStore(OneElt, Gep, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
336
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
337 // Create "else" block, fill it in the next iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
338 BasicBlock *NewIfBlock =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
339 CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
340 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
341 Instruction *OldBr = IfBlock->getTerminator();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
342 BranchInst::Create(CondBlock, NewIfBlock, Cmp, OldBr);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
343 OldBr->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
344 IfBlock = NewIfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
345 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
346 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
347 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
348
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
349 // Translate a masked gather intrinsic like
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
350 // <16 x i32 > @llvm.masked.gather.v16i32( <16 x i32*> %Ptrs, i32 4,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
351 // <16 x i1> %Mask, <16 x i32> %Src)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
352 // to a chain of basic blocks, with loading element one-by-one if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
353 // the appropriate mask bit is set
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
354 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
355 // % Ptrs = getelementptr i32, i32* %base, <16 x i64> %ind
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
356 // % Mask0 = extractelement <16 x i1> %Mask, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
357 // % ToLoad0 = icmp eq i1 % Mask0, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
358 // br i1 % ToLoad0, label %cond.load, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
359 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
360 // cond.load:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
361 // % Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
362 // % Load0 = load i32, i32* % Ptr0, align 4
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
363 // % Res0 = insertelement <16 x i32> undef, i32 % Load0, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
364 // br label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
365 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
366 // else:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
367 // %res.phi.else = phi <16 x i32>[% Res0, %cond.load], [undef, % 0]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
368 // % Mask1 = extractelement <16 x i1> %Mask, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
369 // % ToLoad1 = icmp eq i1 % Mask1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
370 // br i1 % ToLoad1, label %cond.load1, label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
371 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
372 // cond.load1:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
373 // % Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
374 // % Load1 = load i32, i32* % Ptr1, align 4
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
375 // % Res1 = insertelement <16 x i32> %res.phi.else, i32 % Load1, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
376 // br label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
377 // . . .
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
378 // % Result = select <16 x i1> %Mask, <16 x i32> %res.phi.select, <16 x i32> %Src
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
379 // ret <16 x i32> %Result
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
380 static void scalarizeMaskedGather(CallInst *CI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
381 Value *Ptrs = CI->getArgOperand(0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
382 Value *Alignment = CI->getArgOperand(1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
383 Value *Mask = CI->getArgOperand(2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
384 Value *Src0 = CI->getArgOperand(3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
385
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
386 VectorType *VecType = dyn_cast<VectorType>(CI->getType());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
387
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
388 assert(VecType && "Unexpected return type of masked load intrinsic");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
389
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
390 IRBuilder<> Builder(CI->getContext());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
391 Instruction *InsertPt = CI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
392 BasicBlock *IfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
393 BasicBlock *CondBlock = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
394 BasicBlock *PrevIfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
395 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
396 unsigned AlignVal = cast<ConstantInt>(Alignment)->getZExtValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
397
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
398 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
399
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
400 Value *UndefVal = UndefValue::get(VecType);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
401
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
402 // The result vector
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
403 Value *VResult = UndefVal;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
404 unsigned VectorWidth = VecType->getNumElements();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
405
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
406 // Shorten the way if the mask is a vector of constants.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
407 bool IsConstMask = isa<ConstantVector>(Mask);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
408
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
409 if (IsConstMask) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
410 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
411 if (cast<ConstantVector>(Mask)->getOperand(Idx)->isNullValue())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
412 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
413 Value *Ptr = Builder.CreateExtractElement(Ptrs, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
414 "Ptr" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
415 LoadInst *Load =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
416 Builder.CreateAlignedLoad(Ptr, AlignVal, "Load" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
417 VResult = Builder.CreateInsertElement(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
418 VResult, Load, Builder.getInt32(Idx), "Res" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
419 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
420 Value *NewI = Builder.CreateSelect(Mask, VResult, Src0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
421 CI->replaceAllUsesWith(NewI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
422 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
423 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
424 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
425
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
426 PHINode *Phi = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
427 Value *PrevPhi = UndefVal;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
428
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
429 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
430 // Fill the "else" block, created in the previous iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
431 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
432 // %Mask1 = extractelement <16 x i1> %Mask, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
433 // %ToLoad1 = icmp eq i1 %Mask1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
434 // br i1 %ToLoad1, label %cond.load, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
435 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
436 if (Idx > 0) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
437 Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
438 Phi->addIncoming(VResult, CondBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
439 Phi->addIncoming(PrevPhi, PrevIfBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
440 PrevPhi = Phi;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
441 VResult = Phi;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
442 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
443
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
444 Value *Predicate = Builder.CreateExtractElement(Mask, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
445 "Mask" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
446 Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_EQ, Predicate,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
447 ConstantInt::get(Predicate->getType(), 1),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
448 "ToLoad" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
449
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
450 // Create "cond" block
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
451 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
452 // %EltAddr = getelementptr i32* %1, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
453 // %Elt = load i32* %EltAddr
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
454 // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
455 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
456 CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.load");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
457 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
458
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
459 Value *Ptr = Builder.CreateExtractElement(Ptrs, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
460 "Ptr" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
461 LoadInst *Load =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
462 Builder.CreateAlignedLoad(Ptr, AlignVal, "Load" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
463 VResult = Builder.CreateInsertElement(VResult, Load, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
464 "Res" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
465
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
466 // Create "else" block, fill it in the next iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
467 BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
468 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
469 Instruction *OldBr = IfBlock->getTerminator();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
470 BranchInst::Create(CondBlock, NewIfBlock, Cmp, OldBr);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
471 OldBr->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
472 PrevIfBlock = IfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
473 IfBlock = NewIfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
474 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
475
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
476 Phi = Builder.CreatePHI(VecType, 2, "res.phi.select");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
477 Phi->addIncoming(VResult, CondBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
478 Phi->addIncoming(PrevPhi, PrevIfBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
479 Value *NewI = Builder.CreateSelect(Mask, Phi, Src0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
480 CI->replaceAllUsesWith(NewI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
481 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
482 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
483
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
484 // Translate a masked scatter intrinsic, like
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
485 // void @llvm.masked.scatter.v16i32(<16 x i32> %Src, <16 x i32*>* %Ptrs, i32 4,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
486 // <16 x i1> %Mask)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
487 // to a chain of basic blocks, that stores element one-by-one if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
488 // the appropriate mask bit is set.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
489 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
490 // % Ptrs = getelementptr i32, i32* %ptr, <16 x i64> %ind
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
491 // % Mask0 = extractelement <16 x i1> % Mask, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
492 // % ToStore0 = icmp eq i1 % Mask0, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
493 // br i1 %ToStore0, label %cond.store, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
494 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
495 // cond.store:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
496 // % Elt0 = extractelement <16 x i32> %Src, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
497 // % Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
498 // store i32 %Elt0, i32* % Ptr0, align 4
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
499 // br label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
500 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
501 // else:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
502 // % Mask1 = extractelement <16 x i1> % Mask, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
503 // % ToStore1 = icmp eq i1 % Mask1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
504 // br i1 % ToStore1, label %cond.store1, label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
505 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
506 // cond.store1:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
507 // % Elt1 = extractelement <16 x i32> %Src, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
508 // % Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
509 // store i32 % Elt1, i32* % Ptr1, align 4
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
510 // br label %else2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
511 // . . .
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
512 static void scalarizeMaskedScatter(CallInst *CI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
513 Value *Src = CI->getArgOperand(0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
514 Value *Ptrs = CI->getArgOperand(1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
515 Value *Alignment = CI->getArgOperand(2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
516 Value *Mask = CI->getArgOperand(3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
517
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
518 assert(isa<VectorType>(Src->getType()) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
519 "Unexpected data type in masked scatter intrinsic");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
520 assert(isa<VectorType>(Ptrs->getType()) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
521 isa<PointerType>(Ptrs->getType()->getVectorElementType()) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
522 "Vector of pointers is expected in masked scatter intrinsic");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
523
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
524 IRBuilder<> Builder(CI->getContext());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
525 Instruction *InsertPt = CI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
526 BasicBlock *IfBlock = CI->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
527 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
528 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
529
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
530 unsigned AlignVal = cast<ConstantInt>(Alignment)->getZExtValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
531 unsigned VectorWidth = Src->getType()->getVectorNumElements();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
532
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
533 // Shorten the way if the mask is a vector of constants.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
534 bool IsConstMask = isa<ConstantVector>(Mask);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
535
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
536 if (IsConstMask) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
537 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
538 if (cast<ConstantVector>(Mask)->getOperand(Idx)->isNullValue())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
539 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
540 Value *OneElt = Builder.CreateExtractElement(Src, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
541 "Elt" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
542 Value *Ptr = Builder.CreateExtractElement(Ptrs, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
543 "Ptr" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
544 Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
545 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
546 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
547 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
548 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
549 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
550 // Fill the "else" block, created in the previous iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
551 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
552 // % Mask1 = extractelement <16 x i1> % Mask, i32 Idx
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
553 // % ToStore = icmp eq i1 % Mask1, true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
554 // br i1 % ToStore, label %cond.store, label %else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
555 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
556 Value *Predicate = Builder.CreateExtractElement(Mask, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
557 "Mask" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
558 Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_EQ, Predicate,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
559 ConstantInt::get(Predicate->getType(), 1),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
560 "ToStore" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
561
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
562 // Create "cond" block
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
563 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
564 // % Elt1 = extractelement <16 x i32> %Src, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
565 // % Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
566 // %store i32 % Elt1, i32* % Ptr1
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
567 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
568 BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.store");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
569 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
570
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
571 Value *OneElt = Builder.CreateExtractElement(Src, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
572 "Elt" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
573 Value *Ptr = Builder.CreateExtractElement(Ptrs, Builder.getInt32(Idx),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
574 "Ptr" + Twine(Idx));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
575 Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
576
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
577 // Create "else" block, fill it in the next iteration
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
578 BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
579 Builder.SetInsertPoint(InsertPt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
580 Instruction *OldBr = IfBlock->getTerminator();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
581 BranchInst::Create(CondBlock, NewIfBlock, Cmp, OldBr);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
582 OldBr->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
583 IfBlock = NewIfBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
584 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
585 CI->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
586 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
587
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
588 bool ScalarizeMaskedMemIntrin::runOnFunction(Function &F) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
589 if (skipFunction(F))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
590 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
591
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
592 bool EverMadeChange = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
593
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
594 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
595
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
596 bool MadeChange = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
597 while (MadeChange) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
598 MadeChange = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
599 for (Function::iterator I = F.begin(); I != F.end();) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
600 BasicBlock *BB = &*I++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
601 bool ModifiedDTOnIteration = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
602 MadeChange |= optimizeBlock(*BB, ModifiedDTOnIteration);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
603
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
604 // Restart BB iteration if the dominator tree of the Function was changed
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
605 if (ModifiedDTOnIteration)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
606 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
607 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
608
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
609 EverMadeChange |= MadeChange;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
610 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
611
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
612 return EverMadeChange;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
613 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
614
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
615 bool ScalarizeMaskedMemIntrin::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
616 bool MadeChange = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
617
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
618 BasicBlock::iterator CurInstIterator = BB.begin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
619 while (CurInstIterator != BB.end()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
620 if (CallInst *CI = dyn_cast<CallInst>(&*CurInstIterator++))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
621 MadeChange |= optimizeCallInst(CI, ModifiedDT);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
622 if (ModifiedDT)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
623 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
624 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
625
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
626 return MadeChange;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
627 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
628
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
629 bool ScalarizeMaskedMemIntrin::optimizeCallInst(CallInst *CI,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
630 bool &ModifiedDT) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
631 IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
632 if (II) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
633 switch (II->getIntrinsicID()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
634 default:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
635 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
636 case Intrinsic::masked_load:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
637 // Scalarize unsupported vector masked load
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
638 if (!TTI->isLegalMaskedLoad(CI->getType())) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
639 scalarizeMaskedLoad(CI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
640 ModifiedDT = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
641 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
642 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
643 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
644 case Intrinsic::masked_store:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
645 if (!TTI->isLegalMaskedStore(CI->getArgOperand(0)->getType())) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
646 scalarizeMaskedStore(CI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
647 ModifiedDT = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
648 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
649 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
650 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
651 case Intrinsic::masked_gather:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
652 if (!TTI->isLegalMaskedGather(CI->getType())) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
653 scalarizeMaskedGather(CI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
654 ModifiedDT = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
655 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
656 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
657 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
658 case Intrinsic::masked_scatter:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
659 if (!TTI->isLegalMaskedScatter(CI->getArgOperand(0)->getType())) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
660 scalarizeMaskedScatter(CI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
661 ModifiedDT = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
662 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
663 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
664 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
665 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
666 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
667
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
668 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
669 }