From: Sanjoy Das Date: Mon, 14 Dec 2015 19:11:35 +0000 (+0000) Subject: Teach haveSameSpecialState about operand bundles X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=97a58d8cf4ee932a0ad2b6b75fc5b7743e2e4bde;p=oota-llvm.git Teach haveSameSpecialState about operand bundles git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255527 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index d5a6b6b2fb2..5173658b521 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/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 &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/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index c219121104b..a0bd2c9698e 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -296,11 +296,12 @@ static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2, if (const CallInst *CI = dyn_cast(I1)) return CI->isTailCall() == cast(I2)->isTailCall() && CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == cast(I2)->getAttributes(); + CI->getAttributes() == cast(I2)->getAttributes() && + CI->hasIdenticalOperandBundleSchema(*cast(I2)); if (const InvokeInst *CI = dyn_cast(I1)) return CI->getCallingConv() == cast(I2)->getCallingConv() && - CI->getAttributes() == - cast(I2)->getAttributes(); + CI->getAttributes() == cast(I2)->getAttributes() && + CI->hasIdenticalOperandBundleSchema(*cast(I2)); if (const InsertValueInst *IVI = dyn_cast(I1)) return IVI->getIndices() == cast(I2)->getIndices(); if (const ExtractValueInst *EVI = dyn_cast(I1)) diff --git a/test/Feature/OperandBundles/special-state.ll b/test/Feature/OperandBundles/special-state.ll new file mode 100644 index 00000000000..56e337cc16b --- /dev/null +++ b/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 +}