Currently, the code-model specified in IR can't be captured by [llc].
This patch fixes that.
Reviewed By: shchenz, MaskRay
Differential Revision: https://reviews.llvm.org/D128623
/// Returns the code model. The choices are small, kernel, medium, large, and
/// target default.
- CodeModel::Model getCodeModel() const;
+ CodeModel::Model getCodeModel() const { return CMModel; }
+
+ /// Set the code model.
+ void setCodeModel(CodeModel::Model CM) { CMModel = CM; }
bool isPositionIndependent() const;
/// and dynamic-no-pic.
Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
-/// Returns the code model. The choices are small, kernel, medium, large, and
-/// target default.
-CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; }
-
/// Get the IR-specified TLS model for Var.
static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
switch (GV->getThreadLocalMode()) {
--- /dev/null
+; REQUIRES: x86-registered-target
+; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK-LARGE
+
+;; Check the llc option will override the IR input.
+; RUN: llc -code-model=small %s -o - | FileCheck %s --check-prefix=CHECK-SMALL
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"Code Model", i32 4}
+
+@data = internal constant [0 x i32] []
+
+define i32* @foo() nounwind readonly {
+entry:
+; CHECK-LARGE: movabsq $data, %rax
+; CHECK-SMALL: movl $data, %eax
+ ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
+}
--- /dev/null
+; REQUIRES: x86-registered-target
+; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK-SMALL
+
+;; Check the llc option will override the IR input.
+; RUN: llc -code-model=large %s -o - | FileCheck %s --check-prefix=CHECK-LARGE
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"Code Model", i32 1}
+
+@data = internal constant [0 x i32] []
+
+define i32* @foo() nounwind readonly {
+entry:
+; CHECK-LARGE: movabsq $data, %rax
+; CHECK-SMALL: movl $data, %eax
+ ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
+}
};
Optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
+ Optional<CodeModel::Model> CM = codegen::getExplicitCodeModel();
const Target *TheTarget = nullptr;
std::unique_ptr<TargetMachine> Target;
InitializeOptions(TheTriple);
Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
- TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
- codegen::getExplicitCodeModel(), OLvl));
+ TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl));
assert(Target && "Could not allocate target machine!");
return Target->createDataLayout().getStringRepresentation();
}
if (!TargetTriple.empty())
M->setTargetTriple(Triple::normalize(TargetTriple));
+
+ Optional<CodeModel::Model> CM_IR = M->getCodeModel();
+ if (!CM && CM_IR)
+ Target->setCodeModel(CM_IR.getValue());
} else {
TheTriple = Triple(Triple::normalize(TargetTriple));
if (TheTriple.getTriple().empty())
InitializeOptions(TheTriple);
Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
- TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
- codegen::getExplicitCodeModel(), OLvl));
+ TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl));
assert(Target && "Could not allocate target machine!");
// If we don't have a module then just exit now. We do this down