Bug Summary

File:lib/Target/Mips/MipsAnalyzeImmediate.cpp
Warning:line 44, column 20
The result of the '>>' expression is undefined

Annotated Source Code

1//===-- MipsAnalyzeImmediate.cpp - Analyze Immediates ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "MipsAnalyzeImmediate.h"
10#include "Mips.h"
11#include "llvm/Support/MathExtras.h"
12
13using namespace llvm;
14
15MipsAnalyzeImmediate::Inst::Inst(unsigned O, unsigned I) : Opc(O), ImmOpnd(I) {}
16
17// Add I to the instruction sequences.
18void MipsAnalyzeImmediate::AddInstr(InstSeqLs &SeqLs, const Inst &I) {
19 // Add an instruction seqeunce consisting of just I.
20 if (SeqLs.empty()) {
21 SeqLs.push_back(InstSeq(1, I));
22 return;
23 }
24
25 for (InstSeqLs::iterator Iter = SeqLs.begin(); Iter != SeqLs.end(); ++Iter)
26 Iter->push_back(I);
27}
28
29void MipsAnalyzeImmediate::GetInstSeqLsADDiu(uint64_t Imm, unsigned RemSize,
30 InstSeqLs &SeqLs) {
31 GetInstSeqLs((Imm + 0x8000ULL) & 0xffffffffffff0000ULL, RemSize, SeqLs);
14
Calling 'MipsAnalyzeImmediate::GetInstSeqLs'
32 AddInstr(SeqLs, Inst(ADDiu, Imm & 0xffffULL));
33}
34
35void MipsAnalyzeImmediate::GetInstSeqLsORi(uint64_t Imm, unsigned RemSize,
36 InstSeqLs &SeqLs) {
37 GetInstSeqLs(Imm & 0xffffffffffff0000ULL, RemSize, SeqLs);
23
Calling 'MipsAnalyzeImmediate::GetInstSeqLs'
38 AddInstr(SeqLs, Inst(ORi, Imm & 0xffffULL));
39}
40
41void MipsAnalyzeImmediate::GetInstSeqLsSLL(uint64_t Imm, unsigned RemSize,
42 InstSeqLs &SeqLs) {
43 unsigned Shamt = countTrailingZeros(Imm);
44 GetInstSeqLs(Imm >> Shamt, RemSize - Shamt, SeqLs);
30
The result of the '>>' expression is undefined
45 AddInstr(SeqLs, Inst(SLL, Shamt));
46}
47
48void MipsAnalyzeImmediate::GetInstSeqLs(uint64_t Imm, unsigned RemSize,
49 InstSeqLs &SeqLs) {
50 uint64_t MaskedImm = Imm & (0xffffffffffffffffULL >> (64 - Size));
51
52 // Do nothing if Imm is 0.
53 if (!MaskedImm)
7
Assuming 'MaskedImm' is not equal to 0
8
Taking false branch
15
Assuming 'MaskedImm' is not equal to 0
16
Taking false branch
24
Assuming 'MaskedImm' is not equal to 0
25
Taking false branch
54 return;
55
56 // A single ADDiu will do if RemSize <= 16.
57 if (RemSize <= 16) {
9
Assuming 'RemSize' is > 16
10
Taking false branch
17
Taking false branch
26
Taking false branch
58 AddInstr(SeqLs, Inst(ADDiu, MaskedImm));
59 return;
60 }
61
62 // Shift if the lower 16-bit is cleared.
63 if (!(Imm & 0xffff)) {
11
Assuming the condition is false
12
Taking false branch
18
Assuming the condition is false
19
Taking false branch
27
Assuming the condition is true
28
Taking true branch
64 GetInstSeqLsSLL(Imm, RemSize, SeqLs);
29
Calling 'MipsAnalyzeImmediate::GetInstSeqLsSLL'
65 return;
66 }
67
68 GetInstSeqLsADDiu(Imm, RemSize, SeqLs);
13
Calling 'MipsAnalyzeImmediate::GetInstSeqLsADDiu'
69
70 // If bit 15 is cleared, it doesn't make a difference whether the last
71 // instruction is an ADDiu or ORi. In that case, do not call GetInstSeqLsORi.
72 if (Imm & 0x8000) {
20
Assuming the condition is true
21
Taking true branch
73 InstSeqLs SeqLsORi;
74 GetInstSeqLsORi(Imm, RemSize, SeqLsORi);
22
Calling 'MipsAnalyzeImmediate::GetInstSeqLsORi'
75 SeqLs.append(std::make_move_iterator(SeqLsORi.begin()),
76 std::make_move_iterator(SeqLsORi.end()));
77 }
78}
79
80// Replace a ADDiu & SLL pair with a LUi.
81// e.g. the following two instructions
82// ADDiu 0x0111
83// SLL 18
84// are replaced with
85// LUi 0x444
86void MipsAnalyzeImmediate::ReplaceADDiuSLLWithLUi(InstSeq &Seq) {
87 // Check if the first two instructions are ADDiu and SLL and the shift amount
88 // is at least 16.
89 if ((Seq.size() < 2) || (Seq[0].Opc != ADDiu) ||
90 (Seq[1].Opc != SLL) || (Seq[1].ImmOpnd < 16))
91 return;
92
93 // Sign-extend and shift operand of ADDiu and see if it still fits in 16-bit.
94 int64_t Imm = SignExtend64<16>(Seq[0].ImmOpnd);
95 int64_t ShiftedImm = (uint64_t)Imm << (Seq[1].ImmOpnd - 16);
96
97 if (!isInt<16>(ShiftedImm))
98 return;
99
100 // Replace the first instruction and erase the second.
101 Seq[0].Opc = LUi;
102 Seq[0].ImmOpnd = (unsigned)(ShiftedImm & 0xffff);
103 Seq.erase(Seq.begin() + 1);
104}
105
106void MipsAnalyzeImmediate::GetShortestSeq(InstSeqLs &SeqLs, InstSeq &Insts) {
107 InstSeqLs::iterator ShortestSeq = SeqLs.end();
108 // The length of an instruction sequence is at most 7.
109 unsigned ShortestLength = 8;
110
111 for (InstSeqLs::iterator S = SeqLs.begin(); S != SeqLs.end(); ++S) {
112 ReplaceADDiuSLLWithLUi(*S);
113 assert(S->size() <= 7)((S->size() <= 7) ? static_cast<void> (0) : __assert_fail
("S->size() <= 7", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn301235/lib/Target/Mips/MipsAnalyzeImmediate.cpp"
, 113, __PRETTY_FUNCTION__))
;
114
115 if (S->size() < ShortestLength) {
116 ShortestSeq = S;
117 ShortestLength = S->size();
118 }
119 }
120
121 Insts.clear();
122 Insts.append(ShortestSeq->begin(), ShortestSeq->end());
123}
124
125const MipsAnalyzeImmediate::InstSeq
126&MipsAnalyzeImmediate::Analyze(uint64_t Imm, unsigned Size,
127 bool LastInstrIsADDiu) {
128 this->Size = Size;
129
130 if (Size == 32) {
1
Assuming 'Size' is not equal to 32
2
Taking false branch
131 ADDiu = Mips::ADDiu;
132 ORi = Mips::ORi;
133 SLL = Mips::SLL;
134 LUi = Mips::LUi;
135 } else {
136 ADDiu = Mips::DADDiu;
137 ORi = Mips::ORi64;
138 SLL = Mips::DSLL;
139 LUi = Mips::LUi64;
140 }
141
142 InstSeqLs SeqLs;
143
144 // Get the list of instruction sequences.
145 if (LastInstrIsADDiu | !Imm)
3
Assuming 'Imm' is not equal to 0
4
Assuming the condition is false
5
Taking false branch
146 GetInstSeqLsADDiu(Imm, Size, SeqLs);
147 else
148 GetInstSeqLs(Imm, Size, SeqLs);
6
Calling 'MipsAnalyzeImmediate::GetInstSeqLs'
149
150 // Set Insts to the shortest instruction sequence.
151 GetShortestSeq(SeqLs, Insts);
152
153 return Insts;
154}