| 1 | //===- llvm/BundleAttributes.cpp - LLVM Bundle Attributes -------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/IR/BundleAttributes.h" |
| 10 | |
| 11 | #include "llvm/ADT/StringSwitch.h" |
| 12 | #include "llvm/IR/Constants.h" |
| 13 | |
| 14 | using namespace llvm; |
| 15 | |
| 16 | StringRef llvm::getNameFromBundleAttr(BundleAttr BA) { |
| 17 | switch (BA) { |
| 18 | #define ATTR(Name, Str) \ |
| 19 | case BundleAttr::Name: \ |
| 20 | return #Str; |
| 21 | #include "llvm/IR/BundleAttributes.def" |
| 22 | case BundleAttr::None: |
| 23 | return "none" ; |
| 24 | } |
| 25 | llvm_unreachable("unknonwn bundle attribute" ); |
| 26 | } |
| 27 | |
| 28 | BundleAttr llvm::getBundleAttrFromID(uint32_t ID) { |
| 29 | switch (ID) { |
| 30 | #define ATTR(Name, Str) \ |
| 31 | case LLVMContext::OB_##Name: \ |
| 32 | return BundleAttr::Name; |
| 33 | #include "llvm/IR/BundleAttributes.def" |
| 34 | default: |
| 35 | return BundleAttr::None; |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | AssumeAlignInfo llvm::getAssumeAlignInfo(OperandBundleUse OBU) { |
| 40 | assert(OBU.getTagID() == LLVMContext::OB_Align && OBU.Inputs.size() >= 2 && |
| 41 | OBU.Inputs.size() <= 3); |
| 42 | AssumeAlignInfo Ret{.Ptr: OBU.Inputs[0], .Alignment: OBU.Inputs[1], .Offset: nullptr, .AlignmentVal: std::nullopt, |
| 43 | .OffsetVal: std::nullopt}; |
| 44 | if (auto *Align = dyn_cast<ConstantInt>(Val: OBU.Inputs[1])) |
| 45 | Ret.AlignmentVal = Align->getZExtValue(); |
| 46 | if (OBU.Inputs.size() == 3) { |
| 47 | Ret.Offset = &OBU.Inputs[2]; |
| 48 | if (auto *Offset = dyn_cast<ConstantInt>(Val: OBU.Inputs[2])) |
| 49 | Ret.OffsetVal = Offset->getZExtValue(); |
| 50 | } else { |
| 51 | Ret.OffsetVal = 0; |
| 52 | } |
| 53 | return Ret; |
| 54 | } |
| 55 | |
| 56 | AssumeNoUndefInfo llvm::getAssumeNoUndefInfo(OperandBundleUse OBU) { |
| 57 | assert(OBU.getTagID() == LLVMContext::OB_NoUndef && OBU.Inputs.size() == 1); |
| 58 | return {.Val: OBU.Inputs[0]}; |
| 59 | } |
| 60 | |
| 61 | AssumeSeparateStorageInfo |
| 62 | llvm::getAssumeSeparateStorageInfo(OperandBundleUse OBU) { |
| 63 | assert(OBU.getTagID() == LLVMContext::OB_SeparateStorage && |
| 64 | OBU.Inputs.size() == 2); |
| 65 | return {.Ptr1: OBU.Inputs[0], .Ptr2: OBU.Inputs[1]}; |
| 66 | } |
| 67 | |
| 68 | AssumeNonNullInfo llvm::getAssumeNonNullInfo(OperandBundleUse OBU) { |
| 69 | assert(OBU.getTagID() == LLVMContext::OB_NonNull && OBU.Inputs.size() == 1); |
| 70 | return {.Ptr: OBU.Inputs[0]}; |
| 71 | } |
| 72 | |
| 73 | AssumeDereferenceableInfo |
| 74 | llvm::getAssumeDereferenceableInfo(OperandBundleUse OBU) { |
| 75 | assert(OBU.getTagID() == LLVMContext::OB_Dereferenceable && |
| 76 | OBU.Inputs.size() == 2); |
| 77 | AssumeDereferenceableInfo Ret{.Ptr: OBU.Inputs[0], .Count: OBU.Inputs[1], .CountVal: std::nullopt}; |
| 78 | |
| 79 | if (auto *Size = dyn_cast<ConstantInt>(Val: OBU.Inputs[1])) |
| 80 | Ret.CountVal = Size->getZExtValue(); |
| 81 | return Ret; |
| 82 | } |
| 83 | |
| 84 | bool llvm::assumeBundleImpliesNonNull(const Value *Val, const Function *Context, |
| 85 | OperandBundleUse OBU) { |
| 86 | switch (getBundleAttrFromOBU(OBU)) { |
| 87 | case BundleAttr::Align: { |
| 88 | auto [Ptr, _, _2, Alignment, Offset] = getAssumeAlignInfo(OBU); |
| 89 | return Ptr == Val && Alignment && Offset && isPowerOf2_64(Value: *Alignment) && |
| 90 | *Offset % *Alignment != 0; |
| 91 | } |
| 92 | |
| 93 | case BundleAttr::Dereferenceable: { |
| 94 | auto [Ptr, _, Count] = getAssumeDereferenceableInfo(OBU); |
| 95 | return Ptr == Val && Count && *Count != 0 && |
| 96 | !NullPointerIsDefined(F: Context, |
| 97 | AS: Val->getType()->getPointerAddressSpace()); |
| 98 | } |
| 99 | |
| 100 | case BundleAttr::NonNull: |
| 101 | return getAssumeNonNullInfo(OBU).Ptr == Val; |
| 102 | |
| 103 | default: |
| 104 | return false; |
| 105 | } |
| 106 | } |
| 107 | |