llvm.org GIT mirror llvm / 2079d67
[ConstantHoisting] Avoid hoisting constants in GEPs that index into a struct type. Summary: Indices for GEPs that index into a struct type should always be constants. This added more checks in `collectConstantCandidates:` which make sure constants for GEP pointer type are not hoisted. This fixed Bug https://bugs.llvm.org/show_bug.cgi?id=33538 Reviewers: ributzka, rnk Reviewed By: ributzka Subscribers: efriedma, llvm-commits, srhines, javed.absar, pirama Differential Revision: https://reviews.llvm.org/D34576 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306704 91177308-0d34-0410-b5e6-96231b3b80d8 Leo Li 2 years ago
3 changed file(s) with 100 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
131131 Instruction *Inst, unsigned Idx,
132132 ConstantInt *ConstInt);
133133 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
134 Instruction *Inst, unsigned Idx);
135 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
134136 Instruction *Inst);
135137 void collectConstantCandidates(Function &Fn);
136138 void findAndMakeBaseConstant(ConstCandVecType::iterator S,
3737 #include "llvm/ADT/SmallVector.h"
3838 #include "llvm/ADT/Statistic.h"
3939 #include "llvm/IR/Constants.h"
40 #include "llvm/IR/GetElementPtrTypeIterator.h"
4041 #include "llvm/IR/IntrinsicInst.h"
4142 #include "llvm/Pass.h"
4243 #include "llvm/Support/Debug.h"
339340 }
340341 }
341342
343
344 /// \brief Check the operand for instruction Inst at index Idx.
345 void ConstantHoistingPass::collectConstantCandidates(
346 ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) {
347 Value *Opnd = Inst->getOperand(Idx);
348
349 // Visit constant integers.
350 if (auto ConstInt = dyn_cast(Opnd)) {
351 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
352 return;
353 }
354
355 // Visit cast instructions that have constant integers.
356 if (auto CastInst = dyn_cast(Opnd)) {
357 // Only visit cast instructions, which have been skipped. All other
358 // instructions should have already been visited.
359 if (!CastInst->isCast())
360 return;
361
362 if (auto *ConstInt = dyn_cast(CastInst->getOperand(0))) {
363 // Pretend the constant is directly used by the instruction and ignore
364 // the cast instruction.
365 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
366 return;
367 }
368 }
369
370 // Visit constant expressions that have constant integers.
371 if (auto ConstExpr = dyn_cast(Opnd)) {
372 // Only visit constant cast expressions.
373 if (!ConstExpr->isCast())
374 return;
375
376 if (auto ConstInt = dyn_cast(ConstExpr->getOperand(0))) {
377 // Pretend the constant is directly used by the instruction and ignore
378 // the constant expression.
379 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
380 return;
381 }
382 }
383 }
384
385
342386 /// \brief Scan the instruction for expensive integer constants and record them
343387 /// in the constant candidate vector.
344388 void ConstantHoistingPass::collectConstantCandidates(
364408 if (AI && AI->isStaticAlloca())
365409 return;
366410
411 // Constants in GEPs that index into a struct type should not be hoisted.
412 if (isa(Inst)) {
413 gep_type_iterator GTI = gep_type_begin(Inst);
414
415 // Collect constant for first operand.
416 collectConstantCandidates(ConstCandMap, Inst, 0);
417 // Scan rest operands.
418 for (unsigned Idx = 1, E = Inst->getNumOperands(); Idx != E; ++Idx, ++GTI) {
419 // Only collect constants that index into a non struct type.
420 if (!GTI.isStruct()) {
421 collectConstantCandidates(ConstCandMap, Inst, Idx);
422 }
423 }
424 return;
425 }
426
367427 // Scan all operands.
368428 for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) {
369 Value *Opnd = Inst->getOperand(Idx);
370
371 // Visit constant integers.
372 if (auto ConstInt = dyn_cast(Opnd)) {
373 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
374 continue;
375 }
376
377 // Visit cast instructions that have constant integers.
378 if (auto CastInst = dyn_cast(Opnd)) {
379 // Only visit cast instructions, which have been skipped. All other
380 // instructions should have already been visited.
381 if (!CastInst->isCast())
382 continue;
383
384 if (auto *ConstInt = dyn_cast(CastInst->getOperand(0))) {
385 // Pretend the constant is directly used by the instruction and ignore
386 // the cast instruction.
387 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
388 continue;
389 }
390 }
391
392 // Visit constant expressions that have constant integers.
393 if (auto ConstExpr = dyn_cast(Opnd)) {
394 // Only visit constant cast expressions.
395 if (!ConstExpr->isCast())
396 continue;
397
398 if (auto ConstInt = dyn_cast(ConstExpr->getOperand(0))) {
399 // Pretend the constant is directly used by the instruction and ignore
400 // the constant expression.
401 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
402 continue;
403 }
404 }
429 collectConstantCandidates(ConstCandMap, Inst, Idx);
405430 } // end of for all operands
406431 }
407432
0 ; RUN: opt -consthoist -S < %s | FileCheck %s
1 target triple = "thumbv6m-none-eabi"
2
3 %T = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
4 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
5 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
6 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
7 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
8 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
9 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
10 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
11 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
12 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
13 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
14 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
15 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
16 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
17 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
18 i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
19 i32, i32, i32, i32, i32, i32 }
20
21 ; Indices for GEPs that index into a struct type should not be hoisted.
22 define i32 @test1(%T* %P) nounwind {
23 ; CHECK-LABEL: @test1
24 ; CHECK: %const = bitcast i32 256 to i32
25 ; CHECK: %addr1 = getelementptr %T, %T* %P, i32 %const, i32 256
26 ; CHECK: %addr2 = getelementptr %T, %T* %P, i32 %const, i32 256
27 ; The first index into the pointer is hoisted, but the second one into the
28 ; struct isn't.
29 %addr1 = getelementptr %T, %T* %P, i32 256, i32 256
30 %tmp1 = load i32, i32* %addr1
31 %addr2 = getelementptr %T, %T* %P, i32 256, i32 256
32 %tmp2 = load i32, i32* %addr2
33 %tmp4 = add i32 %tmp1, %tmp2
34 ret i32 %tmp4
35 }
36