1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

Create instruction classes for identifying any atomicity of memory intrinsic. (NFC)

Summary:
For reference, see: http://lists.llvm.org/pipermail/llvm-dev/2017-August/116589.html

This patch fleshes out the instruction class hierarchy with respect to atomic and
non-atomic memory intrinsics. With this change, the relevant part of the class
hierarchy becomes:

IntrinsicInst
  -> MemIntrinsicBase (methods-only class)
    -> MemIntrinsic (non-atomic intrinsics)
      -> MemSetInst
      -> MemTransferInst
        -> MemCpyInst
        -> MemMoveInst
    -> AtomicMemIntrinsic (atomic intrinsics)
      -> AtomicMemSetInst
      -> AtomicMemTransferInst
        -> AtomicMemCpyInst
        -> AtomicMemMoveInst
    -> AnyMemIntrinsic (both atomicities)
      -> AnyMemSetInst
      -> AnyMemTransferInst
        -> AnyMemCpyInst
        -> AnyMemMoveInst

This involves some class renaming:
    ElementUnorderedAtomicMemCpyInst -> AtomicMemCpyInst
    ElementUnorderedAtomicMemMoveInst -> AtomicMemMoveInst
    ElementUnorderedAtomicMemSetInst -> AtomicMemSetInst
A script for doing this renaming in downstream trees is included below.

An example of where the Any* classes should be used in LLVM is when reasoning
about the effects of an instruction (ex: aliasing).

---
Script for renaming AtomicMem* classes:
PREFIXES="[<,([:space:]]"
CLASSES="MemIntrinsic|MemTransferInst|MemSetInst|MemMoveInst|MemCpyInst"
SUFFIXES="[;)>,[:space:]]"

REGEX="(${PREFIXES})ElementUnorderedAtomic(${CLASSES})(${SUFFIXES})"
REGEX2="visitElementUnorderedAtomic(${CLASSES})"

FILES=$( grep -E "(${REGEX}|${REGEX2})" -r . | tr ':' ' ' | awk '{print $1}' | sort | uniq )

SED_SCRIPT="s~${REGEX}~\1Atomic\2\3~g"
SED_SCRIPT2="s~${REGEX2}~visitAtomic\1~g"

for f in $FILES; do
    echo "Processing: $f"
    sed  -i ".bak" -E "${SED_SCRIPT};${SED_SCRIPT2};${EA_SED_SCRIPT};${EA_SED_SCRIPT2}" $f
done

Reviewers: sanjoy, deadalnix, apilipenko, anna, skatkov, mkazantsev

Reviewed By: sanjoy

Subscribers: hfinkel, jholewinski, arsenm, sdardis, nhaehnle, JDevlieghere, javed.absar, llvm-commits

Differential Revision: https://reviews.llvm.org/D38419

llvm-svn: 316950
This commit is contained in:
Daniel Neilson 2017-10-30 19:51:48 +00:00
parent 67b94b1157
commit 0ad57a67a0
5 changed files with 265 additions and 233 deletions

View File

@ -213,12 +213,13 @@ namespace llvm {
}
};
/// This class represents atomic memcpy intrinsic
/// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
/// C&P of all methods from that hierarchy
class ElementUnorderedAtomicMemCpyInst : public IntrinsicInst {
/// Common base class for all memory intrinsics. Simply provides
/// common methods.
/// Written as CRTP to avoid a common base class amongst the
/// three atomicity hierarchies.
template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
private:
enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
enum { ARG_DEST = 0, ARG_LENGTH = 2 };
public:
Value *getRawDest() const {
@ -227,21 +228,42 @@ namespace llvm {
const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
/// Return the arguments to the instruction.
Value *getRawSource() const {
return const_cast<Value *>(getArgOperand(ARG_SOURCE));
}
const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
Value *getLength() const {
return const_cast<Value *>(getArgOperand(ARG_LENGTH));
}
const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
bool isVolatile() const { return false; }
/// This is just like getRawDest, but it strips off any cast
/// instructions (including addrspacecast) that feed it, giving the
/// original input. The returned value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
"setDest called with pointer of wrong type!");
setArgOperand(ARG_DEST, Ptr);
}
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(ARG_LENGTH, L);
}
};
// The common base class for the atomic memset/memmove/memcpy intrinsics
// i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
private:
enum { ARG_ELEMENTSIZE = 3 };
public:
Value *getRawElementSizeInBytes() const {
return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
}
@ -254,43 +276,6 @@ namespace llvm {
return getElementSizeInBytesCst()->getZExtValue();
}
/// This is just like getRawDest, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
/// This is just like getRawSource, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getSource() const { return getRawSource()->stripPointerCasts(); }
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
unsigned getSourceAddressSpace() const {
return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
}
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
"setDest called with pointer of wrong type!");
setArgOperand(ARG_DEST, Ptr);
}
void setSource(Value *Ptr) {
assert(getRawSource()->getType() == Ptr->getType() &&
"setSource called with pointer of wrong type!");
setArgOperand(ARG_SOURCE, Ptr);
}
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(ARG_LENGTH, L);
}
void setElementSizeInBytes(Constant *V) {
assert(V->getType() == Type::getInt8Ty(getContext()) &&
"setElementSizeInBytes called with value of wrong type!");
@ -298,24 +283,54 @@ namespace llvm {
}
static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
case Intrinsic::memset_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
class ElementUnorderedAtomicMemMoveInst : public IntrinsicInst {
/// This class represents atomic memset intrinsic
// i.e. llvm.element.unordered.atomic.memset
class AtomicMemSetInst : public AtomicMemIntrinsic {
private:
enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
enum { ARG_VALUE = 1 };
public:
Value *getRawDest() const {
return const_cast<Value *>(getArgOperand(ARG_DEST));
Value *getValue() const {
return const_cast<Value *>(getArgOperand(ARG_VALUE));
}
const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
void setValue(Value *Val) {
assert(getValue()->getType() == Val->getType() &&
"setValue called with value of wrong type!");
setArgOperand(ARG_VALUE, Val);
}
static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
// This class wraps the atomic memcpy/memmove intrinsics
// i.e. llvm.element.unordered.atomic.memcpy/memmove
class AtomicMemTransferInst : public AtomicMemIntrinsic {
private:
enum { ARG_SOURCE = 1 };
public:
/// Return the arguments to the instruction.
Value *getRawSource() const {
return const_cast<Value *>(getArgOperand(ARG_SOURCE));
@ -323,170 +338,67 @@ namespace llvm {
const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
Value *getLength() const {
return const_cast<Value *>(getArgOperand(ARG_LENGTH));
}
const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
bool isVolatile() const { return false; }
Value *getRawElementSizeInBytes() const {
return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
}
ConstantInt *getElementSizeInBytesCst() const {
return cast<ConstantInt>(getRawElementSizeInBytes());
}
uint32_t getElementSizeInBytes() const {
return getElementSizeInBytesCst()->getZExtValue();
}
/// This is just like getRawDest, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
/// This is just like getRawSource, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getSource() const { return getRawSource()->stripPointerCasts(); }
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
unsigned getSourceAddressSpace() const {
return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
}
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
"setDest called with pointer of wrong type!");
setArgOperand(ARG_DEST, Ptr);
}
void setSource(Value *Ptr) {
assert(getRawSource()->getType() == Ptr->getType() &&
"setSource called with pointer of wrong type!");
setArgOperand(ARG_SOURCE, Ptr);
}
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(ARG_LENGTH, L);
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
return true;
default:
return false;
}
}
void setElementSizeInBytes(Constant *V) {
assert(V->getType() == Type::getInt8Ty(getContext()) &&
"setElementSizeInBytes called with value of wrong type!");
setArgOperand(ARG_ELEMENTSIZE, V);
}
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
}
static inline bool classof(const Value *V) {
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This class represents atomic memset intrinsic
/// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
/// C&P of all methods from that hierarchy
class ElementUnorderedAtomicMemSetInst : public IntrinsicInst {
private:
enum { ARG_DEST = 0, ARG_VALUE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
/// This class represents the atomic memcpy intrinsic
/// i.e. llvm.element.unordered.atomic.memcpy
class AtomicMemCpyInst : public AtomicMemTransferInst {
public:
Value *getRawDest() const {
return const_cast<Value *>(getArgOperand(ARG_DEST));
static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
}
const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
Value *getValue() const { return const_cast<Value*>(getArgOperand(ARG_VALUE)); }
const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
Value *getLength() const {
return const_cast<Value *>(getArgOperand(ARG_LENGTH));
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
};
bool isVolatile() const { return false; }
Value *getRawElementSizeInBytes() const {
return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
/// This class represents the atomic memmove intrinsic
/// i.e. llvm.element.unordered.atomic.memmove
class AtomicMemMoveInst : public AtomicMemTransferInst {
public:
static bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
}
ConstantInt *getElementSizeInBytesCst() const {
return cast<ConstantInt>(getRawElementSizeInBytes());
}
uint32_t getElementSizeInBytes() const {
return getElementSizeInBytesCst()->getZExtValue();
}
/// This is just like getRawDest, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
"setDest called with pointer of wrong type!");
setArgOperand(ARG_DEST, Ptr);
}
void setValue(Value *Val) {
assert(getValue()->getType() == Val->getType() &&
"setValue called with value of wrong type!");
setArgOperand(ARG_VALUE, Val);
}
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(ARG_LENGTH, L);
}
void setElementSizeInBytes(Constant *V) {
assert(V->getType() == Type::getInt8Ty(getContext()) &&
"setElementSizeInBytes called with value of wrong type!");
setArgOperand(ARG_ELEMENTSIZE, V);
}
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
}
static inline bool classof(const Value *V) {
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This is the common base class for memset/memcpy/memmove.
class MemIntrinsic : public IntrinsicInst {
class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
private:
enum { ARG_ALIGN = 3, ARG_VOLATILE = 4 };
public:
Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); }
const Use &getRawDestUse() const { return getArgOperandUse(0); }
Use &getRawDestUse() { return getArgOperandUse(0); }
Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); }
const Use &getLengthUse() const { return getArgOperandUse(2); }
Use &getLengthUse() { return getArgOperandUse(2); }
ConstantInt *getAlignmentCst() const {
return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));
return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_ALIGN)));
}
unsigned getAlignment() const {
@ -494,45 +406,20 @@ namespace llvm {
}
ConstantInt *getVolatileCst() const {
return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4)));
return cast<ConstantInt>(
const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
}
bool isVolatile() const {
return !getVolatileCst()->isZero();
}
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
void setAlignment(Constant *A) { setArgOperand(ARG_ALIGN, A); }
/// This is just like getRawDest, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
"setDest called with pointer of wrong type!");
setArgOperand(0, Ptr);
}
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(2, L);
}
void setAlignment(Constant* A) {
setArgOperand(3, A);
}
void setVolatile(Constant* V) {
setArgOperand(4, V);
}
void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
Type *getAlignmentType() const {
return getArgOperand(3)->getType();
return getArgOperand(ARG_ALIGN)->getType();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -630,6 +517,155 @@ namespace llvm {
}
};
// The common base class for any memset/memmove/memcpy intrinsics;
// whether they be atomic or non-atomic.
// i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
// and llvm.memset/memcpy/memmove
class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
public:
bool isVolatile() const {
// Only the non-atomic intrinsics can be volatile
if (auto *MI = dyn_cast<MemIntrinsic>(this))
return MI->isVolatile();
return false;
}
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy:
case Intrinsic::memmove:
case Intrinsic::memset:
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
case Intrinsic::memset_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This class represents any memset intrinsic
// i.e. llvm.element.unordered.atomic.memset
// and llvm.memset
class AnyMemSetInst : public AnyMemIntrinsic {
private:
enum { ARG_VALUE = 1 };
public:
Value *getValue() const {
return const_cast<Value *>(getArgOperand(ARG_VALUE));
}
const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
void setValue(Value *Val) {
assert(getValue()->getType() == Val->getType() &&
"setValue called with value of wrong type!");
setArgOperand(ARG_VALUE, Val);
}
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memset:
case Intrinsic::memset_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
// This class wraps any memcpy/memmove intrinsics
// i.e. llvm.element.unordered.atomic.memcpy/memmove
// and llvm.memcpy/memmove
class AnyMemTransferInst : public AnyMemIntrinsic {
private:
enum { ARG_SOURCE = 1 };
public:
/// Return the arguments to the instruction.
Value *getRawSource() const {
return const_cast<Value *>(getArgOperand(ARG_SOURCE));
}
const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
/// This is just like getRawSource, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
Value *getSource() const { return getRawSource()->stripPointerCasts(); }
unsigned getSourceAddressSpace() const {
return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
}
void setSource(Value *Ptr) {
assert(getRawSource()->getType() == Ptr->getType() &&
"setSource called with pointer of wrong type!");
setArgOperand(ARG_SOURCE, Ptr);
}
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy:
case Intrinsic::memmove:
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This class represents any memcpy intrinsic
/// i.e. llvm.element.unordered.atomic.memcpy
/// and llvm.memcpy
class AnyMemCpyInst : public AnyMemTransferInst {
public:
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memcpy:
case Intrinsic::memcpy_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This class represents any memmove intrinsic
/// i.e. llvm.element.unordered.atomic.memmove
/// and llvm.memmove
class AnyMemMoveInst : public AnyMemTransferInst {
public:
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::memmove:
case Intrinsic::memmove_element_unordered_atomic:
return true;
default:
return false;
}
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This represents the llvm.va_start intrinsic.
class VAStartInst : public IntrinsicInst {
public:

View File

@ -5044,8 +5044,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
}
case Intrinsic::memcpy_element_unordered_atomic: {
const ElementUnorderedAtomicMemCpyInst &MI =
cast<ElementUnorderedAtomicMemCpyInst>(I);
const AtomicMemCpyInst &MI = cast<AtomicMemCpyInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Src = getValue(MI.getRawSource());
SDValue Length = getValue(MI.getLength());
@ -5083,7 +5082,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
}
case Intrinsic::memmove_element_unordered_atomic: {
auto &MI = cast<ElementUnorderedAtomicMemMoveInst>(I);
auto &MI = cast<AtomicMemMoveInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Src = getValue(MI.getRawSource());
SDValue Length = getValue(MI.getLength());
@ -5121,7 +5120,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
}
case Intrinsic::memset_element_unordered_atomic: {
auto &MI = cast<ElementUnorderedAtomicMemSetInst>(I);
auto &MI = cast<AtomicMemSetInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Val = getValue(MI.getValue());
SDValue Length = getValue(MI.getLength());

View File

@ -4029,9 +4029,7 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
break;
}
case Intrinsic::memcpy_element_unordered_atomic: {
const ElementUnorderedAtomicMemCpyInst *MI =
cast<ElementUnorderedAtomicMemCpyInst>(CS.getInstruction());
;
const AtomicMemCpyInst *MI = cast<AtomicMemCpyInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());
@ -4066,7 +4064,7 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
break;
}
case Intrinsic::memmove_element_unordered_atomic: {
auto *MI = cast<ElementUnorderedAtomicMemMoveInst>(CS.getInstruction());
auto *MI = cast<AtomicMemMoveInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());
@ -4101,7 +4099,7 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
break;
}
case Intrinsic::memset_element_unordered_atomic: {
auto *MI = cast<ElementUnorderedAtomicMemSetInst>(CS.getInstruction());
auto *MI = cast<AtomicMemSetInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());

View File

@ -106,8 +106,8 @@ static Constant *getNegativeIsTrueBoolVec(ConstantDataVector *V) {
return ConstantVector::get(BoolVec);
}
Instruction *InstCombiner::SimplifyElementUnorderedAtomicMemCpy(
ElementUnorderedAtomicMemCpyInst *AMI) {
Instruction *
InstCombiner::SimplifyElementUnorderedAtomicMemCpy(AtomicMemCpyInst *AMI) {
// Try to unfold this intrinsic into sequence of explicit atomic loads and
// stores.
// First check that number of elements is compile time constant.
@ -1877,7 +1877,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
if (Changed) return II;
}
if (auto *AMI = dyn_cast<ElementUnorderedAtomicMemCpyInst>(II)) {
if (auto *AMI = dyn_cast<AtomicMemCpyInst>(II)) {
if (Constant *C = dyn_cast<Constant>(AMI->getLength()))
if (C->isNullValue())
return eraseInstFromFunction(*AMI);

View File

@ -789,8 +789,7 @@ private:
Instruction *MatchBSwap(BinaryOperator &I);
bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
Instruction *
SimplifyElementUnorderedAtomicMemCpy(ElementUnorderedAtomicMemCpyInst *AMI);
Instruction *SimplifyElementUnorderedAtomicMemCpy(AtomicMemCpyInst *AMI);
Instruction *SimplifyMemTransfer(MemIntrinsic *MI);
Instruction *SimplifyMemSet(MemSetInst *MI);