diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-12-14 19:11:35 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-12-14 19:11:35 +0000 |
commit | 2de4d0aa18ef099d41ff07878dcad2d796b1e31e (patch) | |
tree | 04764ab765734d7ba8e9913ff339696980d37b92 | |
parent | d44a1fd506a748122ebdf2053cebc09b737159d6 (diff) | |
download | bcm5719-llvm-2de4d0aa18ef099d41ff07878dcad2d796b1e31e.tar.gz bcm5719-llvm-2de4d0aa18ef099d41ff07878dcad2d796b1e31e.zip |
Teach haveSameSpecialState about operand bundles
llvm-svn: 255527
-rw-r--r-- | llvm/include/llvm/IR/InstrTypes.h | 16 | ||||
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Feature/OperandBundles/special-state.ll | 21 |
3 files changed, 41 insertions, 3 deletions
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index d5a6b6b2fb2..5173658b521 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1447,6 +1447,18 @@ public: return OBU.operandHasAttr(OpIdx - BOI.Begin, A); } + /// \brief Return true if \p Other has the same sequence of operand bundle + /// tags with the same number of operands on each one of them as this + /// OperandBundleUser. + bool hasIdenticalOperandBundleSchema( + const OperandBundleUser<InstrTy, OpIteratorTy> &Other) const { + if (getNumOperandBundles() != Other.getNumOperandBundles()) + return false; + + return std::equal(bundle_op_info_begin(), bundle_op_info_end(), + Other.bundle_op_info_begin()); + }; + protected: /// \brief Is the function attribute S disallowed by some operand bundle on /// this operand bundle user? @@ -1490,6 +1502,10 @@ protected: /// \brief The index in the Use& vector where operands for this operand /// bundle ends. uint32_t End; + + bool operator==(const BundleOpInfo &Other) const { + return Tag == Other.Tag && Begin == Other.Begin && End == Other.End; + } }; /// \brief Simple helper function to map a BundleOpInfo to an diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index c219121104b..a0bd2c9698e 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -296,11 +296,12 @@ static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2, if (const CallInst *CI = dyn_cast<CallInst>(I1)) return CI->isTailCall() == cast<CallInst>(I2)->isTailCall() && CI->getCallingConv() == cast<CallInst>(I2)->getCallingConv() && - CI->getAttributes() == cast<CallInst>(I2)->getAttributes(); + CI->getAttributes() == cast<CallInst>(I2)->getAttributes() && + CI->hasIdenticalOperandBundleSchema(*cast<CallInst>(I2)); if (const InvokeInst *CI = dyn_cast<InvokeInst>(I1)) return CI->getCallingConv() == cast<InvokeInst>(I2)->getCallingConv() && - CI->getAttributes() == - cast<InvokeInst>(I2)->getAttributes(); + CI->getAttributes() == cast<InvokeInst>(I2)->getAttributes() && + CI->hasIdenticalOperandBundleSchema(*cast<InvokeInst>(I2)); if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(I1)) return IVI->getIndices() == cast<InsertValueInst>(I2)->getIndices(); if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I1)) diff --git a/llvm/test/Feature/OperandBundles/special-state.ll b/llvm/test/Feature/OperandBundles/special-state.ll new file mode 100644 index 00000000000..56e337cc16b --- /dev/null +++ b/llvm/test/Feature/OperandBundles/special-state.ll @@ -0,0 +1,21 @@ +; RUN: opt -S -early-cse < %s | FileCheck %s + +; This test isn't directly related to EarlyCSE or varargs. It is just +; using these as a vehicle for testing the correctness of +; haveSameSpecialState around operand bundles. + +declare i32 @foo(...) + +define i32 @f() { +; CHECK-LABEL: @f( + entry: +; CHECK: %v0 = call i32 (...) @foo( +; CHECK: %v1 = call i32 (...) @foo( +; CHECK: %v = add i32 %v0, %v1 +; CHECK: ret i32 %v + + %v0 = call i32 (...) @foo(i32 10) readonly [ "foo"(i32 20) ] + %v1 = call i32 (...) @foo() readonly [ "foo"(i32 10, i32 20) ] + %v = add i32 %v0, %v1 + ret i32 %v +} |