#define LLVM_IR_AUTOUPGRADE_H
#include "llvm/ADT/StringRef.h"
+#include <vector>
namespace llvm {
class AttrBuilder;
class Type;
class Value;
+ template <typename T> class OperandBundleDefT;
+ using OperandBundleDef = OperandBundleDefT<Value *>;
+
/// This is a more granular function that simply checks an intrinsic function
/// for upgrading, and returns true if it requires upgrading. It may return
/// null in NewFn if the all calls to the original intrinsic function
/// Upgrade attributes that changed format or kind.
void UpgradeAttributes(AttrBuilder &B);
+ /// Upgrade operand bundles (without knowing about their user instruction).
+ void UpgradeOperandBundles(std::vector<OperandBundleDef> &OperandBundles);
+
} // End llvm namespace
#endif
}
}
+ // Upgrade the bundles if needed.
+ if (!OperandBundles.empty())
+ UpgradeOperandBundles(OperandBundles);
+
I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops,
OperandBundles);
ResTypeID = getContainedTypeID(FTyID);
}
}
+ // Upgrade the bundles if needed.
+ if (!OperandBundles.empty())
+ UpgradeOperandBundles(OperandBundles);
+
I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args,
OperandBundles);
ResTypeID = getContainedTypeID(FTyID);
}
}
+ // Upgrade the bundles if needed.
+ if (!OperandBundles.empty())
+ UpgradeOperandBundles(OperandBundles);
+
I = CallInst::Create(FTy, Callee, Args, OperandBundles);
ResTypeID = getContainedTypeID(FTyID);
OperandBundles.clear();
B.addAttribute(Attribute::NullPointerIsValid);
}
}
+
+void llvm::UpgradeOperandBundles(std::vector<OperandBundleDef> &Bundles) {
+
+ // clang.arc.attachedcall bundles are now required to have an operand.
+ // If they don't, it's okay to drop them entirely: when there is an operand,
+ // the "attachedcall" is meaningful and required, but without an operand,
+ // it's just a marker NOP. Dropping it merely prevents an optimization.
+ erase_if(Bundles, [&](OperandBundleDef &OBD) {
+ return OBD.getTag() == "clang.arc.attachedcall" &&
+ OBD.inputs().empty();
+ });
+}
--- /dev/null
+; Test that nullary clang.arc.attachedcall operand bundles are "upgraded".
+
+; RUN: llvm-dis %s.bc -o - | FileCheck %s
+; RUN: verify-uselistorder %s.bc
+
+define i8* @invalid() {
+; CHECK-LABEL: define i8* @invalid() {
+; CHECK-NEXT: %tmp0 = call i8* @foo(){{$}}
+; CHECK-NEXT: ret i8* %tmp0
+ %tmp0 = call i8* @foo() [ "clang.arc.attachedcall"() ]
+ ret i8* %tmp0
+}
+
+define i8* @valid() {
+; CHECK-LABEL: define i8* @valid() {
+; CHECK-NEXT: %tmp0 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+; CHECK-NEXT: ret i8* %tmp0
+ %tmp0 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+ ret i8* %tmp0
+}
+
+declare i8* @foo()
+declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)