1bc76dadbSSam Parker //===----- TypePromotion.cpp ----------------------------------------------===//
2bc76dadbSSam Parker //
3bc76dadbSSam Parker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bc76dadbSSam Parker // See https://llvm.org/LICENSE.txt for license information.
5bc76dadbSSam Parker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bc76dadbSSam Parker //
7bc76dadbSSam Parker //===----------------------------------------------------------------------===//
8bc76dadbSSam Parker //
9bc76dadbSSam Parker /// \file
10bc76dadbSSam Parker /// This is an opcode based type promotion pass for small types that would
11bc76dadbSSam Parker /// otherwise be promoted during legalisation. This works around the limitations
12bc76dadbSSam Parker /// of selection dag for cyclic regions. The search begins from icmp
13bc76dadbSSam Parker /// instructions operands where a tree, consisting of non-wrapping or safe
14bc76dadbSSam Parker /// wrapping instructions, is built, checked and promoted if possible.
15bc76dadbSSam Parker ///
16bc76dadbSSam Parker //===----------------------------------------------------------------------===//
17bc76dadbSSam Parker
18bc76dadbSSam Parker #include "llvm/ADT/SetVector.h"
19bc76dadbSSam Parker #include "llvm/ADT/StringRef.h"
20933de407SSam Parker #include "llvm/Analysis/TargetTransformInfo.h"
21bc76dadbSSam Parker #include "llvm/CodeGen/Passes.h"
22bc76dadbSSam Parker #include "llvm/CodeGen/TargetLowering.h"
23bc76dadbSSam Parker #include "llvm/CodeGen/TargetPassConfig.h"
24bc76dadbSSam Parker #include "llvm/CodeGen/TargetSubtargetInfo.h"
25bc76dadbSSam Parker #include "llvm/IR/Attributes.h"
26bc76dadbSSam Parker #include "llvm/IR/BasicBlock.h"
27a278250bSNico Weber #include "llvm/IR/Constants.h"
28989f1c72Sserge-sans-paille #include "llvm/IR/IRBuilder.h"
29bc76dadbSSam Parker #include "llvm/IR/InstrTypes.h"
30bc76dadbSSam Parker #include "llvm/IR/Instruction.h"
31bc76dadbSSam Parker #include "llvm/IR/Instructions.h"
32bc76dadbSSam Parker #include "llvm/IR/Type.h"
33bc76dadbSSam Parker #include "llvm/IR/Value.h"
34bc76dadbSSam Parker #include "llvm/InitializePasses.h"
35bc76dadbSSam Parker #include "llvm/Pass.h"
36bc76dadbSSam Parker #include "llvm/Support/Casting.h"
37bc76dadbSSam Parker #include "llvm/Support/CommandLine.h"
38fe0006c8SSimon Pilgrim #include "llvm/Target/TargetMachine.h"
39bc76dadbSSam Parker
40bc76dadbSSam Parker #define DEBUG_TYPE "type-promotion"
41bc76dadbSSam Parker #define PASS_NAME "Type Promotion"
42bc76dadbSSam Parker
43bc76dadbSSam Parker using namespace llvm;
44bc76dadbSSam Parker
45764a7f48SDavid Green static cl::opt<bool> DisablePromotion("disable-type-promotion", cl::Hidden,
46764a7f48SDavid Green cl::init(false),
47bc76dadbSSam Parker cl::desc("Disable type promotion pass"));
48bc76dadbSSam Parker
49bc76dadbSSam Parker // The goal of this pass is to enable more efficient code generation for
50bc76dadbSSam Parker // operations on narrow types (i.e. types with < 32-bits) and this is a
51bc76dadbSSam Parker // motivating IR code example:
52bc76dadbSSam Parker //
53bc76dadbSSam Parker // define hidden i32 @cmp(i8 zeroext) {
54bc76dadbSSam Parker // %2 = add i8 %0, -49
55bc76dadbSSam Parker // %3 = icmp ult i8 %2, 3
56bc76dadbSSam Parker // ..
57bc76dadbSSam Parker // }
58bc76dadbSSam Parker //
59bc76dadbSSam Parker // The issue here is that i8 is type-legalized to i32 because i8 is not a
60bc76dadbSSam Parker // legal type. Thus, arithmetic is done in integer-precision, but then the
61bc76dadbSSam Parker // byte value is masked out as follows:
62bc76dadbSSam Parker //
63bc76dadbSSam Parker // t19: i32 = add t4, Constant:i32<-49>
64bc76dadbSSam Parker // t24: i32 = and t19, Constant:i32<255>
65bc76dadbSSam Parker //
66bc76dadbSSam Parker // Consequently, we generate code like this:
67bc76dadbSSam Parker //
68bc76dadbSSam Parker // subs r0, #49
69bc76dadbSSam Parker // uxtb r1, r0
70bc76dadbSSam Parker // cmp r1, #3
71bc76dadbSSam Parker //
72bc76dadbSSam Parker // This shows that masking out the byte value results in generation of
73bc76dadbSSam Parker // the UXTB instruction. This is not optimal as r0 already contains the byte
74bc76dadbSSam Parker // value we need, and so instead we can just generate:
75bc76dadbSSam Parker //
76bc76dadbSSam Parker // sub.w r1, r0, #49
77bc76dadbSSam Parker // cmp r1, #3
78bc76dadbSSam Parker //
79bc76dadbSSam Parker // We achieve this by type promoting the IR to i32 like so for this example:
80bc76dadbSSam Parker //
81bc76dadbSSam Parker // define i32 @cmp(i8 zeroext %c) {
82bc76dadbSSam Parker // %0 = zext i8 %c to i32
83bc76dadbSSam Parker // %c.off = add i32 %0, -49
84bc76dadbSSam Parker // %1 = icmp ult i32 %c.off, 3
85bc76dadbSSam Parker // ..
86bc76dadbSSam Parker // }
87bc76dadbSSam Parker //
88bc76dadbSSam Parker // For this to be valid and legal, we need to prove that the i32 add is
89bc76dadbSSam Parker // producing the same value as the i8 addition, and that e.g. no overflow
90bc76dadbSSam Parker // happens.
91bc76dadbSSam Parker //
92bc76dadbSSam Parker // A brief sketch of the algorithm and some terminology.
93bc76dadbSSam Parker // We pattern match interesting IR patterns:
94bc76dadbSSam Parker // - which have "sources": instructions producing narrow values (i8, i16), and
95bc76dadbSSam Parker // - they have "sinks": instructions consuming these narrow values.
96bc76dadbSSam Parker //
97bc76dadbSSam Parker // We collect all instruction connecting sources and sinks in a worklist, so
98bc76dadbSSam Parker // that we can mutate these instruction and perform type promotion when it is
99bc76dadbSSam Parker // legal to do so.
100bc76dadbSSam Parker
101bc76dadbSSam Parker namespace {
102bc76dadbSSam Parker class IRPromoter {
10342dba633SSam Parker LLVMContext &Ctx;
10442dba633SSam Parker unsigned PromotedWidth = 0;
1053c7f740fSSam Parker SetVector<Value *> &Visited;
1063c7f740fSSam Parker SetVector<Value *> &Sources;
1073c7f740fSSam Parker SetVector<Instruction *> &Sinks;
108355ee18cSDavid Green SmallPtrSetImpl<Instruction *> &SafeWrap;
10942dba633SSam Parker IntegerType *ExtTy = nullptr;
110bc76dadbSSam Parker SmallPtrSet<Value *, 8> NewInsts;
111bc76dadbSSam Parker SmallPtrSet<Instruction *, 4> InstsToRemove;
112bc76dadbSSam Parker DenseMap<Value *, SmallVector<Type *, 4>> TruncTysMap;
113bc76dadbSSam Parker SmallPtrSet<Value *, 8> Promoted;
114bc76dadbSSam Parker
115bc76dadbSSam Parker void ReplaceAllUsersOfWith(Value *From, Value *To);
1167e163afdSKazu Hirata void ExtendSources();
1177e163afdSKazu Hirata void ConvertTruncs();
1187e163afdSKazu Hirata void PromoteTree();
1197e163afdSKazu Hirata void TruncateSinks();
1207e163afdSKazu Hirata void Cleanup();
121bc76dadbSSam Parker
122bc76dadbSSam Parker public:
IRPromoter(LLVMContext & C,unsigned Width,SetVector<Value * > & visited,SetVector<Value * > & sources,SetVector<Instruction * > & sinks,SmallPtrSetImpl<Instruction * > & wrap)123e0fe9785SSam Parker IRPromoter(LLVMContext &C, unsigned Width,
1243c7f740fSSam Parker SetVector<Value *> &visited, SetVector<Value *> &sources,
1253c7f740fSSam Parker SetVector<Instruction *> &sinks,
126355ee18cSDavid Green SmallPtrSetImpl<Instruction *> &wrap)
127e0fe9785SSam Parker : Ctx(C), PromotedWidth(Width), Visited(visited),
1283c7f740fSSam Parker Sources(sources), Sinks(sinks), SafeWrap(wrap) {
12942dba633SSam Parker ExtTy = IntegerType::get(Ctx, PromotedWidth);
13042dba633SSam Parker }
131bc76dadbSSam Parker
1323c7f740fSSam Parker void Mutate();
133bc76dadbSSam Parker };
134bc76dadbSSam Parker
135bc76dadbSSam Parker class TypePromotion : public FunctionPass {
13642dba633SSam Parker unsigned TypeSize = 0;
13742dba633SSam Parker LLVMContext *Ctx = nullptr;
13842dba633SSam Parker unsigned RegisterBitWidth = 0;
139bc76dadbSSam Parker SmallPtrSet<Value *, 16> AllVisited;
140bc76dadbSSam Parker SmallPtrSet<Instruction *, 8> SafeToPromote;
141355ee18cSDavid Green SmallPtrSet<Instruction *, 4> SafeWrap;
142bc76dadbSSam Parker
14342dba633SSam Parker // Does V have the same size result type as TypeSize.
14442dba633SSam Parker bool EqualTypeSize(Value *V);
14542dba633SSam Parker // Does V have the same size, or narrower, result type as TypeSize.
14642dba633SSam Parker bool LessOrEqualTypeSize(Value *V);
14742dba633SSam Parker // Does V have a result type that is wider than TypeSize.
14842dba633SSam Parker bool GreaterThanTypeSize(Value *V);
14942dba633SSam Parker // Does V have a result type that is narrower than TypeSize.
15042dba633SSam Parker bool LessThanTypeSize(Value *V);
15142dba633SSam Parker // Should V be a leaf in the promote tree?
15242dba633SSam Parker bool isSource(Value *V);
15342dba633SSam Parker // Should V be a root in the promotion tree?
15442dba633SSam Parker bool isSink(Value *V);
15542dba633SSam Parker // Should we change the result type of V? It will result in the users of V
15642dba633SSam Parker // being visited.
15742dba633SSam Parker bool shouldPromote(Value *V);
15842dba633SSam Parker // Is I an add or a sub, which isn't marked as nuw, but where a wrapping
15942dba633SSam Parker // result won't affect the computation?
160bc76dadbSSam Parker bool isSafeWrap(Instruction *I);
16142dba633SSam Parker // Can V have its integer type promoted, or can the type be ignored.
16242dba633SSam Parker bool isSupportedType(Value *V);
16342dba633SSam Parker // Is V an instruction with a supported opcode or another value that we can
16442dba633SSam Parker // handle, such as constants and basic blocks.
165bc76dadbSSam Parker bool isSupportedValue(Value *V);
16642dba633SSam Parker // Is V an instruction thats result can trivially promoted, or has safe
16742dba633SSam Parker // wrapping.
168bc76dadbSSam Parker bool isLegalToPromote(Value *V);
169bc76dadbSSam Parker bool TryToPromote(Value *V, unsigned PromotedWidth);
170bc76dadbSSam Parker
171bc76dadbSSam Parker public:
172bc76dadbSSam Parker static char ID;
173bc76dadbSSam Parker
TypePromotion()174bc76dadbSSam Parker TypePromotion() : FunctionPass(ID) {}
175bc76dadbSSam Parker
getAnalysisUsage(AnalysisUsage & AU) const176bc76dadbSSam Parker void getAnalysisUsage(AnalysisUsage &AU) const override {
177933de407SSam Parker AU.addRequired<TargetTransformInfoWrapperPass>();
178bc76dadbSSam Parker AU.addRequired<TargetPassConfig>();
179c49611f9SDavid Green AU.setPreservesCFG();
180bc76dadbSSam Parker }
181bc76dadbSSam Parker
getPassName() const182bc76dadbSSam Parker StringRef getPassName() const override { return PASS_NAME; }
183bc76dadbSSam Parker
184bc76dadbSSam Parker bool runOnFunction(Function &F) override;
185bc76dadbSSam Parker };
186bc76dadbSSam Parker
187764a7f48SDavid Green } // namespace
188bc76dadbSSam Parker
GenerateSignBits(Instruction * I)189c60a4c1bSCraig Topper static bool GenerateSignBits(Instruction *I) {
190c60a4c1bSCraig Topper unsigned Opc = I->getOpcode();
191bc76dadbSSam Parker return Opc == Instruction::AShr || Opc == Instruction::SDiv ||
192bc76dadbSSam Parker Opc == Instruction::SRem || Opc == Instruction::SExt;
193bc76dadbSSam Parker }
194bc76dadbSSam Parker
EqualTypeSize(Value * V)19542dba633SSam Parker bool TypePromotion::EqualTypeSize(Value *V) {
19642dba633SSam Parker return V->getType()->getScalarSizeInBits() == TypeSize;
197bc76dadbSSam Parker }
198bc76dadbSSam Parker
LessOrEqualTypeSize(Value * V)19942dba633SSam Parker bool TypePromotion::LessOrEqualTypeSize(Value *V) {
20042dba633SSam Parker return V->getType()->getScalarSizeInBits() <= TypeSize;
201bc76dadbSSam Parker }
202bc76dadbSSam Parker
GreaterThanTypeSize(Value * V)20342dba633SSam Parker bool TypePromotion::GreaterThanTypeSize(Value *V) {
20442dba633SSam Parker return V->getType()->getScalarSizeInBits() > TypeSize;
205bc76dadbSSam Parker }
206bc76dadbSSam Parker
LessThanTypeSize(Value * V)20742dba633SSam Parker bool TypePromotion::LessThanTypeSize(Value *V) {
20842dba633SSam Parker return V->getType()->getScalarSizeInBits() < TypeSize;
209bc76dadbSSam Parker }
210bc76dadbSSam Parker
211bc76dadbSSam Parker /// Return true if the given value is a source in the use-def chain, producing
212bc76dadbSSam Parker /// a narrow 'TypeSize' value. These values will be zext to start the promotion
213bc76dadbSSam Parker /// of the tree to i32. We guarantee that these won't populate the upper bits
214bc76dadbSSam Parker /// of the register. ZExt on the loads will be free, and the same for call
215bc76dadbSSam Parker /// return values because we only accept ones that guarantee a zeroext ret val.
216bc76dadbSSam Parker /// Many arguments will have the zeroext attribute too, so those would be free
217bc76dadbSSam Parker /// too.
isSource(Value * V)21842dba633SSam Parker bool TypePromotion::isSource(Value *V) {
219bc76dadbSSam Parker if (!isa<IntegerType>(V->getType()))
220bc76dadbSSam Parker return false;
221bc76dadbSSam Parker
222bc76dadbSSam Parker // TODO Allow zext to be sources.
223bc76dadbSSam Parker if (isa<Argument>(V))
224bc76dadbSSam Parker return true;
225bc76dadbSSam Parker else if (isa<LoadInst>(V))
226bc76dadbSSam Parker return true;
227bc76dadbSSam Parker else if (isa<BitCastInst>(V))
228bc76dadbSSam Parker return true;
229bc76dadbSSam Parker else if (auto *Call = dyn_cast<CallInst>(V))
230bc76dadbSSam Parker return Call->hasRetAttr(Attribute::AttrKind::ZExt);
231bc76dadbSSam Parker else if (auto *Trunc = dyn_cast<TruncInst>(V))
232bc76dadbSSam Parker return EqualTypeSize(Trunc);
233bc76dadbSSam Parker return false;
234bc76dadbSSam Parker }
235bc76dadbSSam Parker
236bc76dadbSSam Parker /// Return true if V will require any promoted values to be truncated for the
237bc76dadbSSam Parker /// the IR to remain valid. We can't mutate the value type of these
238bc76dadbSSam Parker /// instructions.
isSink(Value * V)23942dba633SSam Parker bool TypePromotion::isSink(Value *V) {
240bc76dadbSSam Parker // TODO The truncate also isn't actually necessary because we would already
241bc76dadbSSam Parker // proved that the data value is kept within the range of the original data
242e0fe9785SSam Parker // type. We currently remove any truncs inserted for handling zext sinks.
243bc76dadbSSam Parker
244bc76dadbSSam Parker // Sinks are:
245bc76dadbSSam Parker // - points where the value in the register is being observed, such as an
246bc76dadbSSam Parker // icmp, switch or store.
247bc76dadbSSam Parker // - points where value types have to match, such as calls and returns.
248bc76dadbSSam Parker // - zext are included to ease the transformation and are generally removed
249bc76dadbSSam Parker // later on.
250bc76dadbSSam Parker if (auto *Store = dyn_cast<StoreInst>(V))
251bc76dadbSSam Parker return LessOrEqualTypeSize(Store->getValueOperand());
252bc76dadbSSam Parker if (auto *Return = dyn_cast<ReturnInst>(V))
253bc76dadbSSam Parker return LessOrEqualTypeSize(Return->getReturnValue());
254bc76dadbSSam Parker if (auto *ZExt = dyn_cast<ZExtInst>(V))
255bc76dadbSSam Parker return GreaterThanTypeSize(ZExt);
256bc76dadbSSam Parker if (auto *Switch = dyn_cast<SwitchInst>(V))
257bc76dadbSSam Parker return LessThanTypeSize(Switch->getCondition());
258bc76dadbSSam Parker if (auto *ICmp = dyn_cast<ICmpInst>(V))
259bc76dadbSSam Parker return ICmp->isSigned() || LessThanTypeSize(ICmp->getOperand(0));
260bc76dadbSSam Parker
261bc76dadbSSam Parker return isa<CallInst>(V);
262bc76dadbSSam Parker }
263bc76dadbSSam Parker
264bc76dadbSSam Parker /// Return whether this instruction can safely wrap.
isSafeWrap(Instruction * I)265bc76dadbSSam Parker bool TypePromotion::isSafeWrap(Instruction *I) {
266764a7f48SDavid Green // We can support a potentially wrapping instruction (I) if:
267bc76dadbSSam Parker // - It is only used by an unsigned icmp.
268bc76dadbSSam Parker // - The icmp uses a constant.
269bc76dadbSSam Parker // - The wrapping value (I) is decreasing, i.e would underflow - wrapping
270bc76dadbSSam Parker // around zero to become a larger number than before.
271bc76dadbSSam Parker // - The wrapping instruction (I) also uses a constant.
272bc76dadbSSam Parker //
273bc76dadbSSam Parker // We can then use the two constants to calculate whether the result would
274bc76dadbSSam Parker // wrap in respect to itself in the original bitwidth. If it doesn't wrap,
275bc76dadbSSam Parker // just underflows the range, the icmp would give the same result whether the
276bc76dadbSSam Parker // result has been truncated or not. We calculate this by:
27709632919SCraig Topper // - Zero extending both constants, if needed, to RegisterBitWidth.
278bc76dadbSSam Parker // - Take the absolute value of I's constant, adding this to the icmp const.
279bc76dadbSSam Parker // - Check that this value is not out of range for small type. If it is, it
280bc76dadbSSam Parker // means that it has underflowed enough to wrap around the icmp constant.
281bc76dadbSSam Parker //
282bc76dadbSSam Parker // For example:
283bc76dadbSSam Parker //
284bc76dadbSSam Parker // %sub = sub i8 %a, 2
285bc76dadbSSam Parker // %cmp = icmp ule i8 %sub, 254
286bc76dadbSSam Parker //
287bc76dadbSSam Parker // If %a = 0, %sub = -2 == FE == 254
288bc76dadbSSam Parker // But if this is evalulated as a i32
289bc76dadbSSam Parker // %sub = -2 == FF FF FF FE == 4294967294
290bc76dadbSSam Parker // So the unsigned compares (i8 and i32) would not yield the same result.
291bc76dadbSSam Parker //
292bc76dadbSSam Parker // Another way to look at it is:
293bc76dadbSSam Parker // %a - 2 <= 254
294bc76dadbSSam Parker // %a + 2 <= 254 + 2
295bc76dadbSSam Parker // %a <= 256
296bc76dadbSSam Parker // And we can't represent 256 in the i8 format, so we don't support it.
297bc76dadbSSam Parker //
298bc76dadbSSam Parker // Whereas:
299bc76dadbSSam Parker //
300bc76dadbSSam Parker // %sub i8 %a, 1
301bc76dadbSSam Parker // %cmp = icmp ule i8 %sub, 254
302bc76dadbSSam Parker //
303bc76dadbSSam Parker // If %a = 0, %sub = -1 == FF == 255
304bc76dadbSSam Parker // As i32:
305bc76dadbSSam Parker // %sub = -1 == FF FF FF FF == 4294967295
306bc76dadbSSam Parker //
307bc76dadbSSam Parker // In this case, the unsigned compare results would be the same and this
308bc76dadbSSam Parker // would also be true for ult, uge and ugt:
309bc76dadbSSam Parker // - (255 < 254) == (0xFFFFFFFF < 254) == false
310bc76dadbSSam Parker // - (255 <= 254) == (0xFFFFFFFF <= 254) == false
311bc76dadbSSam Parker // - (255 > 254) == (0xFFFFFFFF > 254) == true
312bc76dadbSSam Parker // - (255 >= 254) == (0xFFFFFFFF >= 254) == true
313bc76dadbSSam Parker //
314bc76dadbSSam Parker // To demonstrate why we can't handle increasing values:
315bc76dadbSSam Parker //
316bc76dadbSSam Parker // %add = add i8 %a, 2
317bc76dadbSSam Parker // %cmp = icmp ult i8 %add, 127
318bc76dadbSSam Parker //
319bc76dadbSSam Parker // If %a = 254, %add = 256 == (i8 1)
320bc76dadbSSam Parker // As i32:
321bc76dadbSSam Parker // %add = 256
322bc76dadbSSam Parker //
323bc76dadbSSam Parker // (1 < 127) != (256 < 127)
324bc76dadbSSam Parker
325bc76dadbSSam Parker unsigned Opc = I->getOpcode();
326bc76dadbSSam Parker if (Opc != Instruction::Add && Opc != Instruction::Sub)
327bc76dadbSSam Parker return false;
328bc76dadbSSam Parker
329355ee18cSDavid Green if (!I->hasOneUse() || !isa<ICmpInst>(*I->user_begin()) ||
330bc76dadbSSam Parker !isa<ConstantInt>(I->getOperand(1)))
331bc76dadbSSam Parker return false;
332bc76dadbSSam Parker
333bc76dadbSSam Parker // Don't support an icmp that deals with sign bits.
334bc76dadbSSam Parker auto *CI = cast<ICmpInst>(*I->user_begin());
335bc76dadbSSam Parker if (CI->isSigned() || CI->isEquality())
336bc76dadbSSam Parker return false;
337bc76dadbSSam Parker
338355ee18cSDavid Green ConstantInt *ICmpConstant = nullptr;
339bc76dadbSSam Parker if (auto *Const = dyn_cast<ConstantInt>(CI->getOperand(0)))
340355ee18cSDavid Green ICmpConstant = Const;
341bc76dadbSSam Parker else if (auto *Const = dyn_cast<ConstantInt>(CI->getOperand(1)))
342355ee18cSDavid Green ICmpConstant = Const;
343bc76dadbSSam Parker else
344bc76dadbSSam Parker return false;
345bc76dadbSSam Parker
346355ee18cSDavid Green const APInt &ICmpConst = ICmpConstant->getValue();
347355ee18cSDavid Green APInt OverflowConst = cast<ConstantInt>(I->getOperand(1))->getValue();
348355ee18cSDavid Green if (Opc == Instruction::Sub)
349355ee18cSDavid Green OverflowConst = -OverflowConst;
350355ee18cSDavid Green if (!OverflowConst.isNonPositive())
351bc76dadbSSam Parker return false;
352bc76dadbSSam Parker
353764a7f48SDavid Green // Using C1 = OverflowConst and C2 = ICmpConst, we can either prove that:
354355ee18cSDavid Green // zext(x) + sext(C1) <u zext(C2) if C1 < 0 and C1 >s C2
355355ee18cSDavid Green // zext(x) + sext(C1) <u sext(C2) if C1 < 0 and C1 <=s C2
356355ee18cSDavid Green if (OverflowConst.sgt(ICmpConst)) {
357355ee18cSDavid Green LLVM_DEBUG(dbgs() << "IR Promotion: Allowing safe overflow for sext "
358355ee18cSDavid Green << "const of " << *I << "\n");
359355ee18cSDavid Green SafeWrap.insert(I);
360bc76dadbSSam Parker return true;
361355ee18cSDavid Green } else {
362355ee18cSDavid Green LLVM_DEBUG(dbgs() << "IR Promotion: Allowing safe overflow for sext "
363355ee18cSDavid Green << "const of " << *I << " and " << *CI << "\n");
364355ee18cSDavid Green SafeWrap.insert(I);
365355ee18cSDavid Green SafeWrap.insert(CI);
366355ee18cSDavid Green return true;
367355ee18cSDavid Green }
368355ee18cSDavid Green return false;
369bc76dadbSSam Parker }
370bc76dadbSSam Parker
shouldPromote(Value * V)37142dba633SSam Parker bool TypePromotion::shouldPromote(Value *V) {
372bc76dadbSSam Parker if (!isa<IntegerType>(V->getType()) || isSink(V))
373bc76dadbSSam Parker return false;
374bc76dadbSSam Parker
375bc76dadbSSam Parker if (isSource(V))
376bc76dadbSSam Parker return true;
377bc76dadbSSam Parker
378bc76dadbSSam Parker auto *I = dyn_cast<Instruction>(V);
379bc76dadbSSam Parker if (!I)
380bc76dadbSSam Parker return false;
381bc76dadbSSam Parker
382bc76dadbSSam Parker if (isa<ICmpInst>(I))
383bc76dadbSSam Parker return false;
384bc76dadbSSam Parker
385bc76dadbSSam Parker return true;
386bc76dadbSSam Parker }
387bc76dadbSSam Parker
388bc76dadbSSam Parker /// Return whether we can safely mutate V's type to ExtTy without having to be
389bc76dadbSSam Parker /// concerned with zero extending or truncation.
isPromotedResultSafe(Instruction * I)390c60a4c1bSCraig Topper static bool isPromotedResultSafe(Instruction *I) {
391c60a4c1bSCraig Topper if (GenerateSignBits(I))
392bc76dadbSSam Parker return false;
393bc76dadbSSam Parker
394c60a4c1bSCraig Topper if (!isa<OverflowingBinaryOperator>(I))
395bc76dadbSSam Parker return true;
396bc76dadbSSam Parker
397c60a4c1bSCraig Topper return I->hasNoUnsignedWrap();
398bc76dadbSSam Parker }
399bc76dadbSSam Parker
ReplaceAllUsersOfWith(Value * From,Value * To)400bc76dadbSSam Parker void IRPromoter::ReplaceAllUsersOfWith(Value *From, Value *To) {
401bc76dadbSSam Parker SmallVector<Instruction *, 4> Users;
402bc76dadbSSam Parker Instruction *InstTo = dyn_cast<Instruction>(To);
403bc76dadbSSam Parker bool ReplacedAll = true;
404bc76dadbSSam Parker
405bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Replacing " << *From << " with " << *To
406bc76dadbSSam Parker << "\n");
407bc76dadbSSam Parker
408bc76dadbSSam Parker for (Use &U : From->uses()) {
409bc76dadbSSam Parker auto *User = cast<Instruction>(U.getUser());
410bc76dadbSSam Parker if (InstTo && User->isIdenticalTo(InstTo)) {
411bc76dadbSSam Parker ReplacedAll = false;
412bc76dadbSSam Parker continue;
413bc76dadbSSam Parker }
414bc76dadbSSam Parker Users.push_back(User);
415bc76dadbSSam Parker }
416bc76dadbSSam Parker
417bc76dadbSSam Parker for (auto *U : Users)
418bc76dadbSSam Parker U->replaceUsesOfWith(From, To);
419bc76dadbSSam Parker
420bc76dadbSSam Parker if (ReplacedAll)
421bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(From))
422bc76dadbSSam Parker InstsToRemove.insert(I);
423bc76dadbSSam Parker }
424bc76dadbSSam Parker
ExtendSources()425bc76dadbSSam Parker void IRPromoter::ExtendSources() {
426bc76dadbSSam Parker IRBuilder<> Builder{Ctx};
427bc76dadbSSam Parker
428bc76dadbSSam Parker auto InsertZExt = [&](Value *V, Instruction *InsertPt) {
429bc76dadbSSam Parker assert(V->getType() != ExtTy && "zext already extends to i32");
430bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Inserting ZExt for " << *V << "\n");
431bc76dadbSSam Parker Builder.SetInsertPoint(InsertPt);
432bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(V))
433bc76dadbSSam Parker Builder.SetCurrentDebugLocation(I->getDebugLoc());
434bc76dadbSSam Parker
435bc76dadbSSam Parker Value *ZExt = Builder.CreateZExt(V, ExtTy);
436bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(ZExt)) {
437bc76dadbSSam Parker if (isa<Argument>(V))
438bc76dadbSSam Parker I->moveBefore(InsertPt);
439bc76dadbSSam Parker else
440bc76dadbSSam Parker I->moveAfter(InsertPt);
441bc76dadbSSam Parker NewInsts.insert(I);
442bc76dadbSSam Parker }
443bc76dadbSSam Parker
444bc76dadbSSam Parker ReplaceAllUsersOfWith(V, ZExt);
445bc76dadbSSam Parker };
446bc76dadbSSam Parker
447bc76dadbSSam Parker // Now, insert extending instructions between the sources and their users.
448bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Promoting sources:\n");
4499e6d1f4bSKazu Hirata for (auto *V : Sources) {
450bc76dadbSSam Parker LLVM_DEBUG(dbgs() << " - " << *V << "\n");
451bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(V))
452bc76dadbSSam Parker InsertZExt(I, I);
453bc76dadbSSam Parker else if (auto *Arg = dyn_cast<Argument>(V)) {
454bc76dadbSSam Parker BasicBlock &BB = Arg->getParent()->front();
455bc76dadbSSam Parker InsertZExt(Arg, &*BB.getFirstInsertionPt());
456bc76dadbSSam Parker } else {
457bc76dadbSSam Parker llvm_unreachable("unhandled source that needs extending");
458bc76dadbSSam Parker }
459bc76dadbSSam Parker Promoted.insert(V);
460bc76dadbSSam Parker }
461bc76dadbSSam Parker }
462bc76dadbSSam Parker
PromoteTree()463bc76dadbSSam Parker void IRPromoter::PromoteTree() {
464bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Mutating the tree..\n");
465bc76dadbSSam Parker
466bc76dadbSSam Parker // Mutate the types of the instructions within the tree. Here we handle
467bc76dadbSSam Parker // constant operands.
4683c7f740fSSam Parker for (auto *V : Visited) {
4693c7f740fSSam Parker if (Sources.count(V))
470bc76dadbSSam Parker continue;
471bc76dadbSSam Parker
472bc76dadbSSam Parker auto *I = cast<Instruction>(V);
4733c7f740fSSam Parker if (Sinks.count(I))
474bc76dadbSSam Parker continue;
475bc76dadbSSam Parker
476bc76dadbSSam Parker for (unsigned i = 0, e = I->getNumOperands(); i < e; ++i) {
477bc76dadbSSam Parker Value *Op = I->getOperand(i);
478bc76dadbSSam Parker if ((Op->getType() == ExtTy) || !isa<IntegerType>(Op->getType()))
479bc76dadbSSam Parker continue;
480bc76dadbSSam Parker
481bc76dadbSSam Parker if (auto *Const = dyn_cast<ConstantInt>(Op)) {
4828d3894f6SCraig Topper // For subtract, we don't need to sext the constant. We only put it in
4838d3894f6SCraig Topper // SafeWrap because SafeWrap.size() is used elsewhere.
48446387667SCraig Topper // For cmp, we need to sign extend a constant appearing in either
48546387667SCraig Topper // operand. For add, we should only sign extend the RHS.
48646387667SCraig Topper Constant *NewConst = (SafeWrap.contains(I) &&
48746387667SCraig Topper (I->getOpcode() == Instruction::ICmp || i == 1) &&
4888d3894f6SCraig Topper I->getOpcode() != Instruction::Sub)
489355ee18cSDavid Green ? ConstantExpr::getSExt(Const, ExtTy)
490355ee18cSDavid Green : ConstantExpr::getZExt(Const, ExtTy);
491bc76dadbSSam Parker I->setOperand(i, NewConst);
492bc76dadbSSam Parker } else if (isa<UndefValue>(Op))
493cec249c6SCraig Topper I->setOperand(i, ConstantInt::get(ExtTy, 0));
494bc76dadbSSam Parker }
495bc76dadbSSam Parker
49692abb1cfSCraig Topper // Mutate the result type, unless this is an icmp or switch.
49792abb1cfSCraig Topper if (!isa<ICmpInst>(I) && !isa<SwitchInst>(I)) {
498bc76dadbSSam Parker I->mutateType(ExtTy);
499bc76dadbSSam Parker Promoted.insert(I);
500bc76dadbSSam Parker }
501bc76dadbSSam Parker }
502bc76dadbSSam Parker }
503bc76dadbSSam Parker
TruncateSinks()504bc76dadbSSam Parker void IRPromoter::TruncateSinks() {
505bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Fixing up the sinks:\n");
506bc76dadbSSam Parker
507bc76dadbSSam Parker IRBuilder<> Builder{Ctx};
508bc76dadbSSam Parker
509bc76dadbSSam Parker auto InsertTrunc = [&](Value *V, Type *TruncTy) -> Instruction * {
510bc76dadbSSam Parker if (!isa<Instruction>(V) || !isa<IntegerType>(V->getType()))
511bc76dadbSSam Parker return nullptr;
512bc76dadbSSam Parker
5133c7f740fSSam Parker if ((!Promoted.count(V) && !NewInsts.count(V)) || Sources.count(V))
514bc76dadbSSam Parker return nullptr;
515bc76dadbSSam Parker
516bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Creating " << *TruncTy << " Trunc for "
517bc76dadbSSam Parker << *V << "\n");
518bc76dadbSSam Parker Builder.SetInsertPoint(cast<Instruction>(V));
519bc76dadbSSam Parker auto *Trunc = dyn_cast<Instruction>(Builder.CreateTrunc(V, TruncTy));
520bc76dadbSSam Parker if (Trunc)
521bc76dadbSSam Parker NewInsts.insert(Trunc);
522bc76dadbSSam Parker return Trunc;
523bc76dadbSSam Parker };
524bc76dadbSSam Parker
525bc76dadbSSam Parker // Fix up any stores or returns that use the results of the promoted
526bc76dadbSSam Parker // chain.
5279e6d1f4bSKazu Hirata for (auto *I : Sinks) {
528bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: For Sink: " << *I << "\n");
529bc76dadbSSam Parker
530bc76dadbSSam Parker // Handle calls separately as we need to iterate over arg operands.
531bc76dadbSSam Parker if (auto *Call = dyn_cast<CallInst>(I)) {
532d34cd75dSKazu Hirata for (unsigned i = 0; i < Call->arg_size(); ++i) {
533bc76dadbSSam Parker Value *Arg = Call->getArgOperand(i);
534bc76dadbSSam Parker Type *Ty = TruncTysMap[Call][i];
535bc76dadbSSam Parker if (Instruction *Trunc = InsertTrunc(Arg, Ty)) {
536bc76dadbSSam Parker Trunc->moveBefore(Call);
537bc76dadbSSam Parker Call->setArgOperand(i, Trunc);
538bc76dadbSSam Parker }
539bc76dadbSSam Parker }
540bc76dadbSSam Parker continue;
541bc76dadbSSam Parker }
542bc76dadbSSam Parker
543bc76dadbSSam Parker // Special case switches because we need to truncate the condition.
544bc76dadbSSam Parker if (auto *Switch = dyn_cast<SwitchInst>(I)) {
545bc76dadbSSam Parker Type *Ty = TruncTysMap[Switch][0];
546bc76dadbSSam Parker if (Instruction *Trunc = InsertTrunc(Switch->getCondition(), Ty)) {
547bc76dadbSSam Parker Trunc->moveBefore(Switch);
548bc76dadbSSam Parker Switch->setCondition(Trunc);
549bc76dadbSSam Parker }
550bc76dadbSSam Parker continue;
551bc76dadbSSam Parker }
552bc76dadbSSam Parker
5536d53d35eSSam Parker // Don't insert a trunc for a zext which can still legally promote.
5546d53d35eSSam Parker if (auto ZExt = dyn_cast<ZExtInst>(I))
5556d53d35eSSam Parker if (ZExt->getType()->getScalarSizeInBits() > PromotedWidth)
5566d53d35eSSam Parker continue;
5576d53d35eSSam Parker
558bc76dadbSSam Parker // Now handle the others.
559bc76dadbSSam Parker for (unsigned i = 0; i < I->getNumOperands(); ++i) {
560bc76dadbSSam Parker Type *Ty = TruncTysMap[I][i];
561bc76dadbSSam Parker if (Instruction *Trunc = InsertTrunc(I->getOperand(i), Ty)) {
562bc76dadbSSam Parker Trunc->moveBefore(I);
563bc76dadbSSam Parker I->setOperand(i, Trunc);
564bc76dadbSSam Parker }
565bc76dadbSSam Parker }
566bc76dadbSSam Parker }
567bc76dadbSSam Parker }
568bc76dadbSSam Parker
Cleanup()569bc76dadbSSam Parker void IRPromoter::Cleanup() {
570bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Cleanup..\n");
571bc76dadbSSam Parker // Some zexts will now have become redundant, along with their trunc
5726750e341Schenglin.bi // operands, so remove them.
5739e6d1f4bSKazu Hirata for (auto *V : Visited) {
574bc76dadbSSam Parker if (!isa<ZExtInst>(V))
575bc76dadbSSam Parker continue;
576bc76dadbSSam Parker
577bc76dadbSSam Parker auto ZExt = cast<ZExtInst>(V);
578bc76dadbSSam Parker if (ZExt->getDestTy() != ExtTy)
579bc76dadbSSam Parker continue;
580bc76dadbSSam Parker
581bc76dadbSSam Parker Value *Src = ZExt->getOperand(0);
582bc76dadbSSam Parker if (ZExt->getSrcTy() == ZExt->getDestTy()) {
583bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Removing unnecessary cast: " << *ZExt
584bc76dadbSSam Parker << "\n");
585bc76dadbSSam Parker ReplaceAllUsersOfWith(ZExt, Src);
586bc76dadbSSam Parker continue;
587bc76dadbSSam Parker }
588bc76dadbSSam Parker
589e0fe9785SSam Parker // We've inserted a trunc for a zext sink, but we already know that the
590e0fe9785SSam Parker // input is in range, negating the need for the trunc.
591e0fe9785SSam Parker if (NewInsts.count(Src) && isa<TruncInst>(Src)) {
592bc76dadbSSam Parker auto *Trunc = cast<TruncInst>(Src);
593bc76dadbSSam Parker assert(Trunc->getOperand(0)->getType() == ExtTy &&
594bc76dadbSSam Parker "expected inserted trunc to be operating on i32");
595bc76dadbSSam Parker ReplaceAllUsersOfWith(ZExt, Trunc->getOperand(0));
596bc76dadbSSam Parker }
597bc76dadbSSam Parker }
598bc76dadbSSam Parker
599bc76dadbSSam Parker for (auto *I : InstsToRemove) {
600bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Removing " << *I << "\n");
601bc76dadbSSam Parker I->dropAllReferences();
602bc76dadbSSam Parker I->eraseFromParent();
603bc76dadbSSam Parker }
604bc76dadbSSam Parker }
605bc76dadbSSam Parker
ConvertTruncs()606bc76dadbSSam Parker void IRPromoter::ConvertTruncs() {
607bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Converting truncs..\n");
608bc76dadbSSam Parker IRBuilder<> Builder{Ctx};
609bc76dadbSSam Parker
6103c7f740fSSam Parker for (auto *V : Visited) {
6113c7f740fSSam Parker if (!isa<TruncInst>(V) || Sources.count(V))
612bc76dadbSSam Parker continue;
613bc76dadbSSam Parker
614bc76dadbSSam Parker auto *Trunc = cast<TruncInst>(V);
615bc76dadbSSam Parker Builder.SetInsertPoint(Trunc);
616bc76dadbSSam Parker IntegerType *SrcTy = cast<IntegerType>(Trunc->getOperand(0)->getType());
617bc76dadbSSam Parker IntegerType *DestTy = cast<IntegerType>(TruncTysMap[Trunc][0]);
618bc76dadbSSam Parker
619bc76dadbSSam Parker unsigned NumBits = DestTy->getScalarSizeInBits();
620bc76dadbSSam Parker ConstantInt *Mask =
621bc76dadbSSam Parker ConstantInt::get(SrcTy, APInt::getMaxValue(NumBits).getZExtValue());
622bc76dadbSSam Parker Value *Masked = Builder.CreateAnd(Trunc->getOperand(0), Mask);
623*67fd0d2aSchenglin.bi if (SrcTy != ExtTy)
624*67fd0d2aSchenglin.bi Masked = Builder.CreateTrunc(Masked, ExtTy);
625bc76dadbSSam Parker
626bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(Masked))
627bc76dadbSSam Parker NewInsts.insert(I);
628bc76dadbSSam Parker
629bc76dadbSSam Parker ReplaceAllUsersOfWith(Trunc, Masked);
630bc76dadbSSam Parker }
631bc76dadbSSam Parker }
632bc76dadbSSam Parker
Mutate()6333c7f740fSSam Parker void IRPromoter::Mutate() {
634e0fe9785SSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Promoting use-def chains to "
635e0fe9785SSam Parker << PromotedWidth << "-bits\n");
636bc76dadbSSam Parker
637bc76dadbSSam Parker // Cache original types of the values that will likely need truncating
638bc76dadbSSam Parker for (auto *I : Sinks) {
639bc76dadbSSam Parker if (auto *Call = dyn_cast<CallInst>(I)) {
640d34cd75dSKazu Hirata for (Value *Arg : Call->args())
641bc76dadbSSam Parker TruncTysMap[Call].push_back(Arg->getType());
642bc76dadbSSam Parker } else if (auto *Switch = dyn_cast<SwitchInst>(I))
643bc76dadbSSam Parker TruncTysMap[I].push_back(Switch->getCondition()->getType());
644bc76dadbSSam Parker else {
645bc76dadbSSam Parker for (unsigned i = 0; i < I->getNumOperands(); ++i)
646bc76dadbSSam Parker TruncTysMap[I].push_back(I->getOperand(i)->getType());
647bc76dadbSSam Parker }
648bc76dadbSSam Parker }
649bc76dadbSSam Parker for (auto *V : Visited) {
650bc76dadbSSam Parker if (!isa<TruncInst>(V) || Sources.count(V))
651bc76dadbSSam Parker continue;
652bc76dadbSSam Parker auto *Trunc = cast<TruncInst>(V);
653bc76dadbSSam Parker TruncTysMap[Trunc].push_back(Trunc->getDestTy());
654bc76dadbSSam Parker }
655bc76dadbSSam Parker
656bc76dadbSSam Parker // Insert zext instructions between sources and their users.
657bc76dadbSSam Parker ExtendSources();
658bc76dadbSSam Parker
659bc76dadbSSam Parker // Promote visited instructions, mutating their types in place.
660bc76dadbSSam Parker PromoteTree();
661bc76dadbSSam Parker
662bc76dadbSSam Parker // Convert any truncs, that aren't sources, into AND masks.
663bc76dadbSSam Parker ConvertTruncs();
664bc76dadbSSam Parker
665bc76dadbSSam Parker // Insert trunc instructions for use by calls, stores etc...
666bc76dadbSSam Parker TruncateSinks();
667bc76dadbSSam Parker
668bc76dadbSSam Parker // Finally, remove unecessary zexts and truncs, delete old instructions and
669bc76dadbSSam Parker // clear the data structures.
670bc76dadbSSam Parker Cleanup();
671bc76dadbSSam Parker
672bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Mutation complete\n");
673bc76dadbSSam Parker }
674bc76dadbSSam Parker
67542dba633SSam Parker /// We disallow booleans to make life easier when dealing with icmps but allow
67642dba633SSam Parker /// any other integer that fits in a scalar register. Void types are accepted
67742dba633SSam Parker /// so we can handle switches.
isSupportedType(Value * V)67842dba633SSam Parker bool TypePromotion::isSupportedType(Value *V) {
67942dba633SSam Parker Type *Ty = V->getType();
68042dba633SSam Parker
68142dba633SSam Parker // Allow voids and pointers, these won't be promoted.
68242dba633SSam Parker if (Ty->isVoidTy() || Ty->isPointerTy())
68342dba633SSam Parker return true;
68442dba633SSam Parker
685764a7f48SDavid Green if (!isa<IntegerType>(Ty) || cast<IntegerType>(Ty)->getBitWidth() == 1 ||
68642dba633SSam Parker cast<IntegerType>(Ty)->getBitWidth() > RegisterBitWidth)
68742dba633SSam Parker return false;
68842dba633SSam Parker
68942dba633SSam Parker return LessOrEqualTypeSize(V);
69042dba633SSam Parker }
69142dba633SSam Parker
692bc76dadbSSam Parker /// We accept most instructions, as well as Arguments and ConstantInsts. We
693bc76dadbSSam Parker /// Disallow casts other than zext and truncs and only allow calls if their
694bc76dadbSSam Parker /// return value is zeroext. We don't allow opcodes that can introduce sign
695bc76dadbSSam Parker /// bits.
isSupportedValue(Value * V)696bc76dadbSSam Parker bool TypePromotion::isSupportedValue(Value *V) {
697bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(V)) {
698bc76dadbSSam Parker switch (I->getOpcode()) {
699bc76dadbSSam Parker default:
700bc76dadbSSam Parker return isa<BinaryOperator>(I) && isSupportedType(I) &&
701bc76dadbSSam Parker !GenerateSignBits(I);
702bc76dadbSSam Parker case Instruction::GetElementPtr:
703bc76dadbSSam Parker case Instruction::Store:
704bc76dadbSSam Parker case Instruction::Br:
705bc76dadbSSam Parker case Instruction::Switch:
706bc76dadbSSam Parker return true;
707bc76dadbSSam Parker case Instruction::PHI:
708bc76dadbSSam Parker case Instruction::Select:
709bc76dadbSSam Parker case Instruction::Ret:
710bc76dadbSSam Parker case Instruction::Load:
711bc76dadbSSam Parker case Instruction::Trunc:
712bc76dadbSSam Parker case Instruction::BitCast:
713bc76dadbSSam Parker return isSupportedType(I);
714bc76dadbSSam Parker case Instruction::ZExt:
715bc76dadbSSam Parker return isSupportedType(I->getOperand(0));
716bc76dadbSSam Parker case Instruction::ICmp:
717bc76dadbSSam Parker // Now that we allow small types than TypeSize, only allow icmp of
718bc76dadbSSam Parker // TypeSize because they will require a trunc to be legalised.
719bc76dadbSSam Parker // TODO: Allow icmp of smaller types, and calculate at the end
720bc76dadbSSam Parker // whether the transform would be beneficial.
721bc76dadbSSam Parker if (isa<PointerType>(I->getOperand(0)->getType()))
722bc76dadbSSam Parker return true;
723bc76dadbSSam Parker return EqualTypeSize(I->getOperand(0));
724bc76dadbSSam Parker case Instruction::Call: {
725bc76dadbSSam Parker // Special cases for calls as we need to check for zeroext
726bc76dadbSSam Parker // TODO We should accept calls even if they don't have zeroext, as they
727bc76dadbSSam Parker // can still be sinks.
728bc76dadbSSam Parker auto *Call = cast<CallInst>(I);
729bc76dadbSSam Parker return isSupportedType(Call) &&
730bc76dadbSSam Parker Call->hasRetAttr(Attribute::AttrKind::ZExt);
731bc76dadbSSam Parker }
732bc76dadbSSam Parker }
733bc76dadbSSam Parker } else if (isa<Constant>(V) && !isa<ConstantExpr>(V)) {
734bc76dadbSSam Parker return isSupportedType(V);
735bc76dadbSSam Parker } else if (isa<Argument>(V))
736bc76dadbSSam Parker return isSupportedType(V);
737bc76dadbSSam Parker
738bc76dadbSSam Parker return isa<BasicBlock>(V);
739bc76dadbSSam Parker }
740bc76dadbSSam Parker
741bc76dadbSSam Parker /// Check that the type of V would be promoted and that the original type is
742bc76dadbSSam Parker /// smaller than the targeted promoted type. Check that we're not trying to
743bc76dadbSSam Parker /// promote something larger than our base 'TypeSize' type.
isLegalToPromote(Value * V)744bc76dadbSSam Parker bool TypePromotion::isLegalToPromote(Value *V) {
745bc76dadbSSam Parker auto *I = dyn_cast<Instruction>(V);
746bc76dadbSSam Parker if (!I)
747bc76dadbSSam Parker return true;
748bc76dadbSSam Parker
749bc76dadbSSam Parker if (SafeToPromote.count(I))
750bc76dadbSSam Parker return true;
751bc76dadbSSam Parker
752c60a4c1bSCraig Topper if (isPromotedResultSafe(I) || isSafeWrap(I)) {
753bc76dadbSSam Parker SafeToPromote.insert(I);
754bc76dadbSSam Parker return true;
755bc76dadbSSam Parker }
756bc76dadbSSam Parker return false;
757bc76dadbSSam Parker }
758bc76dadbSSam Parker
TryToPromote(Value * V,unsigned PromotedWidth)759bc76dadbSSam Parker bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
76042dba633SSam Parker Type *OrigTy = V->getType();
761b0ce9f0fSDavid Sherwood TypeSize = OrigTy->getPrimitiveSizeInBits().getFixedSize();
762bc76dadbSSam Parker SafeToPromote.clear();
763bc76dadbSSam Parker SafeWrap.clear();
764bc76dadbSSam Parker
765bc76dadbSSam Parker if (!isSupportedValue(V) || !shouldPromote(V) || !isLegalToPromote(V))
766bc76dadbSSam Parker return false;
767bc76dadbSSam Parker
768bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: TryToPromote: " << *V << ", from "
769bc76dadbSSam Parker << TypeSize << " bits to " << PromotedWidth << "\n");
770bc76dadbSSam Parker
771bc76dadbSSam Parker SetVector<Value *> WorkList;
7723c7f740fSSam Parker SetVector<Value *> Sources;
7733c7f740fSSam Parker SetVector<Instruction *> Sinks;
774bc76dadbSSam Parker SetVector<Value *> CurrentVisited;
775bc76dadbSSam Parker WorkList.insert(V);
776bc76dadbSSam Parker
777bc76dadbSSam Parker // Return true if V was added to the worklist as a supported instruction,
778bc76dadbSSam Parker // if it was already visited, or if we don't need to explore it (e.g.
779bc76dadbSSam Parker // pointer values and GEPs), and false otherwise.
780bc76dadbSSam Parker auto AddLegalInst = [&](Value *V) {
781bc76dadbSSam Parker if (CurrentVisited.count(V))
782bc76dadbSSam Parker return true;
783bc76dadbSSam Parker
784bc76dadbSSam Parker // Ignore GEPs because they don't need promoting and the constant indices
785bc76dadbSSam Parker // will prevent the transformation.
786bc76dadbSSam Parker if (isa<GetElementPtrInst>(V))
787bc76dadbSSam Parker return true;
788bc76dadbSSam Parker
789bc76dadbSSam Parker if (!isSupportedValue(V) || (shouldPromote(V) && !isLegalToPromote(V))) {
790bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Can't handle: " << *V << "\n");
791bc76dadbSSam Parker return false;
792bc76dadbSSam Parker }
793bc76dadbSSam Parker
794bc76dadbSSam Parker WorkList.insert(V);
795bc76dadbSSam Parker return true;
796bc76dadbSSam Parker };
797bc76dadbSSam Parker
798bc76dadbSSam Parker // Iterate through, and add to, a tree of operands and users in the use-def.
799bc76dadbSSam Parker while (!WorkList.empty()) {
8008ba2b628SDiogo Sampaio Value *V = WorkList.pop_back_val();
801bc76dadbSSam Parker if (CurrentVisited.count(V))
802bc76dadbSSam Parker continue;
803bc76dadbSSam Parker
804bc76dadbSSam Parker // Ignore non-instructions, other than arguments.
805bc76dadbSSam Parker if (!isa<Instruction>(V) && !isSource(V))
806bc76dadbSSam Parker continue;
807bc76dadbSSam Parker
808bc76dadbSSam Parker // If we've already visited this value from somewhere, bail now because
809bc76dadbSSam Parker // the tree has already been explored.
810bc76dadbSSam Parker // TODO: This could limit the transform, ie if we try to promote something
811bc76dadbSSam Parker // from an i8 and fail first, before trying an i16.
812bc76dadbSSam Parker if (AllVisited.count(V))
813bc76dadbSSam Parker return false;
814bc76dadbSSam Parker
815bc76dadbSSam Parker CurrentVisited.insert(V);
816bc76dadbSSam Parker AllVisited.insert(V);
817bc76dadbSSam Parker
818bc76dadbSSam Parker // Calls can be both sources and sinks.
819bc76dadbSSam Parker if (isSink(V))
820bc76dadbSSam Parker Sinks.insert(cast<Instruction>(V));
821bc76dadbSSam Parker
822bc76dadbSSam Parker if (isSource(V))
823bc76dadbSSam Parker Sources.insert(V);
824bc76dadbSSam Parker
825bc76dadbSSam Parker if (!isSink(V) && !isSource(V)) {
826bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(V)) {
827bc76dadbSSam Parker // Visit operands of any instruction visited.
828bc76dadbSSam Parker for (auto &U : I->operands()) {
829bc76dadbSSam Parker if (!AddLegalInst(U))
830bc76dadbSSam Parker return false;
831bc76dadbSSam Parker }
832bc76dadbSSam Parker }
833bc76dadbSSam Parker }
834bc76dadbSSam Parker
835bc76dadbSSam Parker // Don't visit users of a node which isn't going to be mutated unless its a
836bc76dadbSSam Parker // source.
837bc76dadbSSam Parker if (isSource(V) || shouldPromote(V)) {
838bc76dadbSSam Parker for (Use &U : V->uses()) {
839bc76dadbSSam Parker if (!AddLegalInst(U.getUser()))
840bc76dadbSSam Parker return false;
841bc76dadbSSam Parker }
842bc76dadbSSam Parker }
843bc76dadbSSam Parker }
844bc76dadbSSam Parker
845764a7f48SDavid Green LLVM_DEBUG({
846764a7f48SDavid Green dbgs() << "IR Promotion: Visited nodes:\n";
847bc76dadbSSam Parker for (auto *I : CurrentVisited)
848bc76dadbSSam Parker I->dump();
849764a7f48SDavid Green });
85042dba633SSam Parker
851bc76dadbSSam Parker unsigned ToPromote = 0;
85242dba633SSam Parker unsigned NonFreeArgs = 0;
85342dba633SSam Parker SmallPtrSet<BasicBlock *, 4> Blocks;
854bc76dadbSSam Parker for (auto *V : CurrentVisited) {
85542dba633SSam Parker if (auto *I = dyn_cast<Instruction>(V))
85642dba633SSam Parker Blocks.insert(I->getParent());
85742dba633SSam Parker
85842dba633SSam Parker if (Sources.count(V)) {
85942dba633SSam Parker if (auto *Arg = dyn_cast<Argument>(V))
86042dba633SSam Parker if (!Arg->hasZExtAttr() && !Arg->hasSExtAttr())
86142dba633SSam Parker ++NonFreeArgs;
862bc76dadbSSam Parker continue;
86342dba633SSam Parker }
86442dba633SSam Parker
865bc76dadbSSam Parker if (Sinks.count(cast<Instruction>(V)))
866bc76dadbSSam Parker continue;
867bc76dadbSSam Parker ++ToPromote;
868bc76dadbSSam Parker }
869bc76dadbSSam Parker
8708ba2b628SDiogo Sampaio // DAG optimizations should be able to handle these cases better, especially
87142dba633SSam Parker // for function arguments.
87242dba633SSam Parker if (ToPromote < 2 || (Blocks.size() == 1 && (NonFreeArgs > SafeWrap.size())))
87342dba633SSam Parker return false;
87442dba633SSam Parker
875e0fe9785SSam Parker IRPromoter Promoter(*Ctx, PromotedWidth, CurrentVisited, Sources, Sinks,
876e0fe9785SSam Parker SafeWrap);
8773c7f740fSSam Parker Promoter.Mutate();
878bc76dadbSSam Parker return true;
879bc76dadbSSam Parker }
880bc76dadbSSam Parker
runOnFunction(Function & F)881bc76dadbSSam Parker bool TypePromotion::runOnFunction(Function &F) {
882bc76dadbSSam Parker if (skipFunction(F) || DisablePromotion)
883bc76dadbSSam Parker return false;
884bc76dadbSSam Parker
885bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Running on " << F.getName() << "\n");
886bc76dadbSSam Parker
887bc76dadbSSam Parker auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
888bc76dadbSSam Parker if (!TPC)
889bc76dadbSSam Parker return false;
890bc76dadbSSam Parker
8918ba2b628SDiogo Sampaio AllVisited.clear();
8928ba2b628SDiogo Sampaio SafeToPromote.clear();
8938ba2b628SDiogo Sampaio SafeWrap.clear();
894bc76dadbSSam Parker bool MadeChange = false;
895bc76dadbSSam Parker const DataLayout &DL = F.getParent()->getDataLayout();
896bc76dadbSSam Parker const TargetMachine &TM = TPC->getTM<TargetMachine>();
897bc76dadbSSam Parker const TargetSubtargetInfo *SubtargetInfo = TM.getSubtargetImpl(F);
898bc76dadbSSam Parker const TargetLowering *TLI = SubtargetInfo->getTargetLowering();
899933de407SSam Parker const TargetTransformInfo &TII =
900933de407SSam Parker getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
90155d18b3cSSander de Smalen RegisterBitWidth =
90255d18b3cSSander de Smalen TII.getRegisterBitWidth(TargetTransformInfo::RGK_Scalar).getFixedSize();
90342dba633SSam Parker Ctx = &F.getParent()->getContext();
904bc76dadbSSam Parker
905bc76dadbSSam Parker // Search up from icmps to try to promote their operands.
906bc76dadbSSam Parker for (BasicBlock &BB : F) {
907764a7f48SDavid Green for (Instruction &I : BB) {
908bc76dadbSSam Parker if (AllVisited.count(&I))
909bc76dadbSSam Parker continue;
910bc76dadbSSam Parker
911bc76dadbSSam Parker if (!isa<ICmpInst>(&I))
912bc76dadbSSam Parker continue;
913bc76dadbSSam Parker
914bc76dadbSSam Parker auto *ICmp = cast<ICmpInst>(&I);
915bc76dadbSSam Parker // Skip signed or pointer compares
916764a7f48SDavid Green if (ICmp->isSigned() || !isa<IntegerType>(ICmp->getOperand(0)->getType()))
917bc76dadbSSam Parker continue;
918bc76dadbSSam Parker
919bc76dadbSSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Searching from: " << *ICmp << "\n");
920bc76dadbSSam Parker
921bc76dadbSSam Parker for (auto &Op : ICmp->operands()) {
922bc76dadbSSam Parker if (auto *I = dyn_cast<Instruction>(Op)) {
923bc76dadbSSam Parker EVT SrcVT = TLI->getValueType(DL, I->getType());
924bc76dadbSSam Parker if (SrcVT.isSimple() && TLI->isTypeLegal(SrcVT.getSimpleVT()))
925bc76dadbSSam Parker break;
926bc76dadbSSam Parker
927764a7f48SDavid Green if (TLI->getTypeAction(*Ctx, SrcVT) !=
928bc76dadbSSam Parker TargetLowering::TypePromoteInteger)
929bc76dadbSSam Parker break;
930764a7f48SDavid Green EVT PromotedVT = TLI->getTypeToTransformTo(*Ctx, SrcVT);
931b0ce9f0fSDavid Sherwood if (RegisterBitWidth < PromotedVT.getFixedSizeInBits()) {
932933de407SSam Parker LLVM_DEBUG(dbgs() << "IR Promotion: Couldn't find target register "
933933de407SSam Parker << "for promoted type\n");
934933de407SSam Parker break;
935933de407SSam Parker }
936933de407SSam Parker
937b0ce9f0fSDavid Sherwood MadeChange |= TryToPromote(I, PromotedVT.getFixedSizeInBits());
938bc76dadbSSam Parker break;
939bc76dadbSSam Parker }
940bc76dadbSSam Parker }
941bc76dadbSSam Parker }
942bc76dadbSSam Parker }
943bc76dadbSSam Parker
9448ba2b628SDiogo Sampaio AllVisited.clear();
9458ba2b628SDiogo Sampaio SafeToPromote.clear();
9468ba2b628SDiogo Sampaio SafeWrap.clear();
9478ba2b628SDiogo Sampaio
948bc76dadbSSam Parker return MadeChange;
949bc76dadbSSam Parker }
950bc76dadbSSam Parker
951bc76dadbSSam Parker INITIALIZE_PASS_BEGIN(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false)
952bc76dadbSSam Parker INITIALIZE_PASS_END(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false)
953bc76dadbSSam Parker
954bc76dadbSSam Parker char TypePromotion::ID = 0;
955bc76dadbSSam Parker
createTypePromotionPass()956764a7f48SDavid Green FunctionPass *llvm::createTypePromotionPass() { return new TypePromotion(); }
957