#ifndef LLVM_CODEGEN_COMMANDFLAGS_H
#define LLVM_CODEGEN_COMMANDFLAGS_H
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm//MC/SubtargetFeature.h"
#include "llvm/Support/CodeGen.h"
return Features.getString();
}
+static inline void overrideFunctionAttributes(StringRef CPU, StringRef Features,
+ Module &M) {
+ for (auto &F : M) {
+ if (!CPU.empty())
+ llvm::overrideFunctionAttribute("target-cpu", CPU, F);
+
+ if (!Features.empty())
+ llvm::overrideFunctionAttribute("target-features", Features, F);
+ }
+}
+
#endif
return F ? &F->getValueSymbolTable() : nullptr;
}
+/// \brief Overwrite attribute Kind in function F.
+void overrideFunctionAttribute(StringRef Kind, StringRef Value, Function &F);
+
} // End llvm namespace
#endif
}
setValueSubclassData(PDData);
}
+
+void llvm::overrideFunctionAttribute(StringRef Kind, StringRef Value,
+ Function &F) {
+ auto &Ctx = F.getContext();
+ AttributeSet Attrs = F.getAttributes(), AttrsToRemove;
+
+ AttrsToRemove =
+ AttrsToRemove.addAttribute(Ctx, AttributeSet::FunctionIndex, Kind);
+ Attrs = Attrs.removeAttributes(Ctx, AttributeSet::FunctionIndex,
+ AttrsToRemove);
+ Attrs = Attrs.addAttribute(Ctx, AttributeSet::FunctionIndex, Kind, Value);
+ F.setAttributes(Attrs);
+}
--- /dev/null
+; RUN: llc < %s -march x86-64 -mcpu=broadwell | FileCheck %s
+; RUN: llc < %s -march x86-64 -mattr=+avx2 | FileCheck %s
+
+; Check that llc can overide function attributes target-cpu and target-features
+; using command line options -mcpu and -mattr.
+
+; CHECK: vpsadbw %ymm{{[0-9]+}}, %ymm{{[0-9]+}}, %ymm{{[0-9]+}}
+
+define <4 x i64> @foo1(<4 x i64> %s1, <4 x i64> %s2) #0 {
+entry:
+ %0 = bitcast <4 x i64> %s1 to <32 x i8>
+ %1 = bitcast <4 x i64> %s2 to <32 x i8>
+ %2 = tail call <4 x i64> @llvm.x86.avx2.psad.bw(<32 x i8> %0, <32 x i8> %1)
+ ret <4 x i64> %2
+}
+
+declare <4 x i64> @llvm.x86.avx2.psad.bw(<32 x i8>, <32 x i8>)
+
+attributes #0 = { "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse4.2,+sse4.1,+sse,+sse2,+sse3,+avx,+popcnt" }
--- /dev/null
+; RUN: opt < %s -mtriple=x86_64-apple-darwin -mcpu=broadwell -mattr=+avx2 -S | FileCheck %s
+
+; Check that opt can rewrite function attributes target-cpu and target-features
+; using command line options -mcpu and -mattr.
+
+; CHECK: attributes #0 = { nounwind readnone ssp uwtable "target-cpu"="broadwell" "target-features"="+avx2" "use-soft-float"="false" }
+
+define i32 @foo1() #0 {
+entry:
+ ret i32 0
+}
+
+attributes #0 = { nounwind readnone ssp uwtable "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3" "use-soft-float"="false" }
}
-; CHECK: declare <2 x double> @llvm.sin.v2f64(<2 x double>) #0
-; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) #0
-; CHECK: declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) #0
-; CHECK: declare <2 x double> @llvm.exp2.v2f64(<2 x double>) #0
+; CHECK: declare <2 x double> @llvm.sin.v2f64(<2 x double>) [[ATTR0:#[0-9]+]]
+; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) [[ATTR0]]
+; CHECK: declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) [[ATTR0]]
+; CHECK: declare <2 x double> @llvm.exp2.v2f64(<2 x double>) [[ATTR0]]
-; CHECK: attributes #0 = { nounwind readnone }
+; CHECK: attributes [[ATTR0]] = { nounwind readnone }
if (const DataLayout *DL = Target->getDataLayout())
M->setDataLayout(*DL);
+ // Override function attributes.
+ overrideFunctionAttributes(CPUStr, FeaturesStr, *M);
+
if (RelaxAll.getNumOccurrences() > 0 &&
FileType != TargetMachine::CGFT_ObjectFile)
errs() << argv[0]
std::unique_ptr<TargetMachine> TM(Machine);
+ // Override function attributes.
+ overrideFunctionAttributes(CPUStr, FeaturesStr, *M);
+
// If the output is set to be emitted to standard out, and standard out is a
// console, print out a warning message and refuse to do it. We don't
// impress anyone by spewing tons of binary goo to a terminal.