OLD | NEW |
1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// | 1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // Verify function-level PNaCl ABI requirements. | 10 // Verify function-level PNaCl ABI requirements. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) | 131 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) |
132 return true; | 132 return true; |
133 | 133 |
134 // Allow some Constants. Note that this excludes ConstantExprs. | 134 // Allow some Constants. Note that this excludes ConstantExprs. |
135 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && | 135 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && |
136 (isa<ConstantInt>(Val) || | 136 (isa<ConstantInt>(Val) || |
137 isa<ConstantFP>(Val) || | 137 isa<ConstantFP>(Val) || |
138 isa<UndefValue>(Val)); | 138 isa<UndefValue>(Val)); |
139 } | 139 } |
140 | 140 |
141 static bool isAllowedAlignment(unsigned Alignment, Type *Ty, bool IsAtomic) { | 141 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) { |
142 if (IsAtomic) { | |
143 // For atomic operations, the alignment must match the size of the type. | |
144 if (Ty->isIntegerTy()) { | |
145 unsigned Bits = Ty->getIntegerBitWidth(); | |
146 return Bits % 8 == 0 && Alignment == Bits / 8; | |
147 } | |
148 return (Ty->isDoubleTy() && Alignment == 8) || | |
149 (Ty->isFloatTy() && Alignment == 4); | |
150 } | |
151 // Non-atomic integer operations must always use "align 1", since we | 142 // Non-atomic integer operations must always use "align 1", since we |
152 // do not want the backend to generate code with non-portable | 143 // do not want the backend to generate code with non-portable |
153 // undefined behaviour (such as misaligned access faults) if user | 144 // undefined behaviour (such as misaligned access faults) if user |
154 // code specifies "align 4" but uses a misaligned pointer. As a | 145 // code specifies "align 4" but uses a misaligned pointer. As a |
155 // concession to performance, we allow larger alignment values for | 146 // concession to performance, we allow larger alignment values for |
156 // floating point types. | 147 // floating point types. |
157 // | 148 // |
158 // To reduce the set of alignment values that need to be encoded in | 149 // To reduce the set of alignment values that need to be encoded in |
159 // pexes, we disallow other alignment values. We require alignments | 150 // pexes, we disallow other alignment values. We require alignments |
160 // to be explicit by disallowing Alignment == 0. | 151 // to be explicit by disallowing Alignment == 0. |
(...skipping 24 matching lines...) Expand all Loading... |
185 case Instruction::Resume: | 176 case Instruction::Resume: |
186 // indirectbr may interfere with streaming | 177 // indirectbr may interfere with streaming |
187 case Instruction::IndirectBr: | 178 case Instruction::IndirectBr: |
188 // No vector instructions yet | 179 // No vector instructions yet |
189 case Instruction::ExtractElement: | 180 case Instruction::ExtractElement: |
190 case Instruction::InsertElement: | 181 case Instruction::InsertElement: |
191 case Instruction::ShuffleVector: | 182 case Instruction::ShuffleVector: |
192 // ExtractValue and InsertValue operate on struct values. | 183 // ExtractValue and InsertValue operate on struct values. |
193 case Instruction::ExtractValue: | 184 case Instruction::ExtractValue: |
194 case Instruction::InsertValue: | 185 case Instruction::InsertValue: |
| 186 // Atomics should become NaCl intrinsics. |
| 187 case Instruction::AtomicCmpXchg: |
| 188 case Instruction::AtomicRMW: |
| 189 case Instruction::Fence: |
195 return "bad instruction opcode"; | 190 return "bad instruction opcode"; |
196 default: | 191 default: |
197 return "unknown instruction opcode"; | 192 return "unknown instruction opcode"; |
198 | 193 |
199 // Terminator instructions | 194 // Terminator instructions |
200 case Instruction::Ret: | 195 case Instruction::Ret: |
201 case Instruction::Br: | 196 case Instruction::Br: |
202 case Instruction::Unreachable: | 197 case Instruction::Unreachable: |
203 // Binary operations | 198 // Binary operations |
204 case Instruction::Add: | 199 case Instruction::Add: |
205 case Instruction::FAdd: | 200 case Instruction::FAdd: |
206 case Instruction::Sub: | 201 case Instruction::Sub: |
207 case Instruction::FSub: | 202 case Instruction::FSub: |
208 case Instruction::Mul: | 203 case Instruction::Mul: |
209 case Instruction::FMul: | 204 case Instruction::FMul: |
210 case Instruction::UDiv: | 205 case Instruction::UDiv: |
211 case Instruction::SDiv: | 206 case Instruction::SDiv: |
212 case Instruction::FDiv: | 207 case Instruction::FDiv: |
213 case Instruction::URem: | 208 case Instruction::URem: |
214 case Instruction::SRem: | 209 case Instruction::SRem: |
215 case Instruction::FRem: | 210 case Instruction::FRem: |
216 // Bitwise binary operations | 211 // Bitwise binary operations |
217 case Instruction::Shl: | 212 case Instruction::Shl: |
218 case Instruction::LShr: | 213 case Instruction::LShr: |
219 case Instruction::AShr: | 214 case Instruction::AShr: |
220 case Instruction::And: | 215 case Instruction::And: |
221 case Instruction::Or: | 216 case Instruction::Or: |
222 case Instruction::Xor: | 217 case Instruction::Xor: |
223 // Memory instructions | |
224 case Instruction::Fence: | |
225 // Conversion operations | 218 // Conversion operations |
226 case Instruction::Trunc: | 219 case Instruction::Trunc: |
227 case Instruction::ZExt: | 220 case Instruction::ZExt: |
228 case Instruction::SExt: | 221 case Instruction::SExt: |
229 case Instruction::FPTrunc: | 222 case Instruction::FPTrunc: |
230 case Instruction::FPExt: | 223 case Instruction::FPExt: |
231 case Instruction::FPToUI: | 224 case Instruction::FPToUI: |
232 case Instruction::FPToSI: | 225 case Instruction::FPToSI: |
233 case Instruction::UIToFP: | 226 case Instruction::UIToFP: |
234 case Instruction::SIToFP: | 227 case Instruction::SIToFP: |
235 // Other operations | 228 // Other operations |
236 case Instruction::ICmp: | 229 case Instruction::ICmp: |
237 case Instruction::FCmp: | 230 case Instruction::FCmp: |
238 case Instruction::PHI: | 231 case Instruction::PHI: |
239 case Instruction::Select: | 232 case Instruction::Select: |
240 break; | 233 break; |
241 | 234 |
242 // Memory accesses. | 235 // Memory accesses. |
243 case Instruction::Load: { | 236 case Instruction::Load: { |
244 const LoadInst *Load = cast<LoadInst>(Inst); | 237 const LoadInst *Load = cast<LoadInst>(Inst); |
| 238 PtrOperandIndex = Load->getPointerOperandIndex(); |
| 239 if (Load->isAtomic()) |
| 240 return "atomic"; |
| 241 if (Load->isVolatile()) |
| 242 return "volatile"; |
245 if (!isAllowedAlignment(Load->getAlignment(), | 243 if (!isAllowedAlignment(Load->getAlignment(), |
246 Load->getType(), | 244 Load->getType())) |
247 Load->isAtomic())) | |
248 return "bad alignment"; | 245 return "bad alignment"; |
249 PtrOperandIndex = 0; | |
250 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 246 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
251 return "bad pointer"; | 247 return "bad pointer"; |
252 break; | 248 break; |
253 } | 249 } |
254 case Instruction::Store: { | 250 case Instruction::Store: { |
255 const StoreInst *Store = cast<StoreInst>(Inst); | 251 const StoreInst *Store = cast<StoreInst>(Inst); |
| 252 PtrOperandIndex = Store->getPointerOperandIndex(); |
| 253 if (Store->isAtomic()) |
| 254 return "atomic"; |
| 255 if (Store->isVolatile()) |
| 256 return "volatile"; |
256 if (!isAllowedAlignment(Store->getAlignment(), | 257 if (!isAllowedAlignment(Store->getAlignment(), |
257 Store->getValueOperand()->getType(), | 258 Store->getValueOperand()->getType())) |
258 Store->isAtomic())) | |
259 return "bad alignment"; | 259 return "bad alignment"; |
260 PtrOperandIndex = 1; | |
261 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 260 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
262 return "bad pointer"; | 261 return "bad pointer"; |
263 break; | 262 break; |
264 } | 263 } |
265 case Instruction::AtomicCmpXchg: | |
266 case Instruction::AtomicRMW: | |
267 PtrOperandIndex = 0; | |
268 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | |
269 return "bad pointer"; | |
270 break; | |
271 | 264 |
272 // Casts. | 265 // Casts. |
273 case Instruction::BitCast: | 266 case Instruction::BitCast: |
274 if (Inst->getType()->isPointerTy()) { | 267 if (Inst->getType()->isPointerTy()) { |
275 PtrOperandIndex = 0; | 268 PtrOperandIndex = 0; |
276 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) | 269 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) |
277 return "operand not InherentPtr"; | 270 return "operand not InherentPtr"; |
278 } | 271 } |
279 break; | 272 break; |
280 case Instruction::IntToPtr: | 273 case Instruction::IntToPtr: |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 } | 440 } |
448 | 441 |
449 char PNaClABIVerifyFunctions::ID = 0; | 442 char PNaClABIVerifyFunctions::ID = 0; |
450 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", | 443 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", |
451 "Verify functions for PNaCl", false, true) | 444 "Verify functions for PNaCl", false, true) |
452 | 445 |
453 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( | 446 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( |
454 PNaClABIErrorReporter *Reporter) { | 447 PNaClABIErrorReporter *Reporter) { |
455 return new PNaClABIVerifyFunctions(Reporter); | 448 return new PNaClABIVerifyFunctions(Reporter); |
456 } | 449 } |
OLD | NEW |