llvm.org GIT mirror llvm / 3695b53
Revert "Re-land r335297 "[X86] Implement more of x86-64 large and medium PIC code models"" Reverting because this is causing failures in the LLDB test suite on GreenDragon. LLVM ERROR: unsupported relocation with subtraction expression, symbol '__GLOBAL_OFFSET_TABLE_' can not be undefined in a subtraction expression git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335894 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 2 years ago
14 changed file(s) with 42 addition(s) and 545 deletion(s). Raw diff Collapse all Expand all
953953
954954 bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP;
955955
956 // We can't use an addressing mode in the 64-bit large code model. In the
957 // medium code model, we use can use an mode when RIP wrappers are present.
958 // That signifies access to globals that are known to be "near", such as the
959 // GOT itself.
956 // Only do this address mode folding for 64-bit if we're in the small code
957 // model.
958 // FIXME: But we can do GOTPCREL addressing in the medium code model.
960959 CodeModel::Model M = TM.getCodeModel();
961 if (Subtarget->is64Bit() &&
962 (M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel)))
960 if (Subtarget->is64Bit() && M != CodeModel::Small && M != CodeModel::Kernel)
963961 return true;
964962
965963 // Base and index reg must be 0 in order to use %rip as base.
3636 def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins i32imm:$label),
3737 "", []>;
3838
39 // 64-bit large code model PIC base construction.
40 let hasSideEffects = 0, mayLoad = 1, isNotDuplicable = 1, SchedRW = [WriteJump] in
41 def MOVGOT64r : PseudoI<(outs GR64:$reg),
42 (ins GR64:$scratch, i64i32imm_pcrel:$got), []>;
4339
4440 // ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into
4541 // a stack adjustment and the codegen must know that they may modify the stack
1124711247 /// TODO: Eliminate this and move the code to X86MachineFunctionInfo.
1124811248 ///
1124911249 unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
11250 assert((!Subtarget.is64Bit() ||
11251 MF->getTarget().getCodeModel() == CodeModel::Medium ||
11252 MF->getTarget().getCodeModel() == CodeModel::Large) &&
11250 assert(!Subtarget.is64Bit() &&
1125311251 "X86-64 PIC uses RIP relative addressing");
1125411252
1125511253 X86MachineFunctionInfo *X86FI = MF->getInfo();
1126011258 // Create the register. The code to initialize it is inserted
1126111259 // later, by the CGBR pass (below).
1126211260 MachineRegisterInfo &RegInfo = MF->getRegInfo();
11263 GlobalBaseReg = RegInfo.createVirtualRegister(
11264 Subtarget.is64Bit() ? &X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass);
11261 GlobalBaseReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass);
1126511262 X86FI->setGlobalBaseReg(GlobalBaseReg);
1126611263 return GlobalBaseReg;
1126711264 }
1263512632 static_cast(&MF.getTarget());
1263612633 const X86Subtarget &STI = MF.getSubtarget();
1263712634
12638 // Don't do anything in the 64-bit small and kernel code models. They use
12639 // RIP-relative addressing for everything.
12640 if (STI.is64Bit() && (TM->getCodeModel() == CodeModel::Small ||
12641 TM->getCodeModel() == CodeModel::Kernel))
12635 // Don't do anything if this is 64-bit as 64-bit PIC
12636 // uses RIP relative addressing.
12637 if (STI.is64Bit())
1264212638 return false;
1264312639
1264412640 // Only emit a global base reg in PIC mode.
1266512661 else
1266612662 PC = GlobalBaseReg;
1266712663
12668 if (STI.is64Bit()) {
12669 if (TM->getCodeModel() == CodeModel::Medium) {
12670 // In the medium code model, use a RIP-relative LEA to materialize the
12671 // GOT.
12672 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PC)
12673 .addReg(X86::RIP)
12674 .addImm(0)
12675 .addReg(0)
12676 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_")
12677 .addReg(0);
12678 } else if (TM->getCodeModel() == CodeModel::Large) {
12679 // Loading the GOT in the large code model requires math with labels,
12680 // so we use a pseudo instruction and expand it during MC emission.
12681 unsigned Scratch = RegInfo.createVirtualRegister(&X86::GR64RegClass);
12682 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVGOT64r), PC)
12683 .addReg(Scratch, RegState::Undef | RegState::Define)
12684 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
12685 } else {
12686 llvm_unreachable("unexpected code model");
12687 }
12688 } else {
12689 // Operand of MovePCtoStack is completely ignored by asm printer. It's
12690 // only used in JIT code emission as displacement to pc.
12691 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVPC32r), PC).addImm(0);
12692
12693 // If we're using vanilla 'GOT' PIC style, we should use relative
12694 // addressing not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
12695 if (STI.isPICStyleGOT()) {
12696 // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel],
12697 // %some_register
12698 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
12699 .addReg(PC)
12700 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
12701 X86II::MO_GOT_ABSOLUTE_ADDRESS);
12702 }
12664 // Operand of MovePCtoStack is completely ignored by asm printer. It's
12665 // only used in JIT code emission as displacement to pc.
12666 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVPC32r), PC).addImm(0);
12667
12668 // If we're using vanilla 'GOT' PIC style, we should use relative addressing
12669 // not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
12670 if (STI.isPICStyleGOT()) {
12671 // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel], %some_register
12672 BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
12673 .addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
12674 X86II::MO_GOT_ABSOLUTE_ADDRESS);
1270312675 }
1270412676
1270512677 return true;
19811981 return;
19821982 }
19831983
1984 case X86::MOVGOT64r: {
1985 // Materializes the GOT for the 64-bit large code model.
1986 MCSymbol *DotSym = OutContext.createTempSymbol();
1987 OutStreamer->EmitLabel(DotSym);
1988
1989 unsigned DstReg = MI->getOperand(0).getReg();
1990 unsigned ScratchReg = MI->getOperand(1).getReg();
1991 MCSymbol *GOTSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
1992
1993 // .LtmpN: leaq .LtmpN(%rip), %dst
1994 const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
1995 EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
1996 .addReg(DstReg) // dest
1997 .addReg(X86::RIP) // base
1998 .addImm(1) // scale
1999 .addReg(0) // index
2000 .addExpr(DotExpr) // disp
2001 .addReg(0)); // seg
2002
2003 // movq $_GLOBAL_OFFSET_TABLE_ - .LtmpN, %scratch
2004 const MCExpr *GOTSymExpr = MCSymbolRefExpr::create(GOTSym, OutContext);
2005 const MCExpr *GOTDiffExpr =
2006 MCBinaryExpr::createSub(GOTSymExpr, DotExpr, OutContext);
2007 EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri)
2008 .addReg(ScratchReg) // dest
2009 .addExpr(GOTDiffExpr)); // disp
2010
2011 // addq %scratch, %dst
2012 EmitAndCountInstruction(MCInstBuilder(X86::ADD64rr)
2013 .addReg(DstReg) // dest
2014 .addReg(DstReg) // dest
2015 .addReg(ScratchReg)); // src
2016 return;
2017 }
2018
20191984 case X86::ADD32ri: {
20201985 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
20211986 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
6767
6868 unsigned char
6969 X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
70 // If we're not PIC, it's not very interesting.
70 // 64 bits can use %rip addressing for anything local.
71 if (is64Bit())
72 return X86II::MO_NO_FLAG;
73
74 // If this is for a position dependent executable, the static linker can
75 // figure it out.
7176 if (!isPositionIndependent())
7277 return X86II::MO_NO_FLAG;
73
74 // For 64-bit, we need to consider the code model.
75 if (is64Bit()) {
76 switch (TM.getCodeModel()) {
77 // 64-bit small code model is simple: All rip-relative.
78 case CodeModel::Small:
79 case CodeModel::Kernel:
80 return X86II::MO_NO_FLAG;
81
82 // The large PIC code model uses GOTOFF.
83 case CodeModel::Large:
84 return X86II::MO_GOTOFF;
85
86 // Medium is a hybrid: RIP-rel for code, GOTOFF for DSO local data.
87 case CodeModel::Medium:
88 if (isa(GV))
89 return X86II::MO_NO_FLAG; // All code is RIP-relative
90 return X86II::MO_GOTOFF; // Local symbols use GOTOFF.
91 }
92 llvm_unreachable("invalid code model");
93 }
9478
9579 // The COFF dynamic linker just patches the executable sections.
9680 if (isTargetCOFF())
11296
11397 unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
11498 const Module &M) const {
115 // The static large model never uses stubs.
116 if (TM.getCodeModel() == CodeModel::Large && !isPositionIndependent())
99 // Large model never uses stubs.
100 if (TM.getCodeModel() == CodeModel::Large)
117101 return X86II::MO_NO_FLAG;
118102
119103 // Absolute symbols can be referenced directly.
135119 if (isTargetCOFF())
136120 return X86II::MO_DLLIMPORT;
137121
138 if (is64Bit() && TM.getCodeModel() != CodeModel::Large)
122 if (is64Bit())
139123 return X86II::MO_GOTPCREL;
140124
141125 if (isTargetDarwin()) {
155155 }
156156
157157 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
158 bool JIT,
159158 Optional RM) {
160159 bool is64Bit = TT.getArch() == Triple::x86_64;
161160 if (!RM.hasValue()) {
162 // JIT codegen should use static relocations by default, since it's
163 // typically executed in process and not relocatable.
164 if (JIT)
165 return Reloc::Static;
166
167161 // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
168162 // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
169163 // use static relocation model by default.
215209 CodeGenOpt::Level OL, bool JIT)
216210 : LLVMTargetMachine(
217211 T, computeDataLayout(TT), TT, CPU, FS, Options,
218 getEffectiveRelocModel(TT, JIT, RM),
212 getEffectiveRelocModel(TT, RM),
219213 getEffectiveCodeModel(CM, JIT, TT.getArch() == Triple::x86_64), OL),
220214 TLOF(createTLOF(getTargetTriple())) {
221215 // Windows stack unwinder gets confused when execution flow "falls through"
None ; RUN: llc -mtriple=x86_64-pc-windows-msvc -code-model=large -relocation-model=static -o - < %s | FileCheck %s
0 ; RUN: llc -mtriple=x86_64-pc-windows-msvc -code-model=large -o - < %s | FileCheck %s
11
22 declare i32 @__CxxFrameHandler3(...)
33
+0
-384
test/CodeGen/X86/code-model.ll less more
None ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; Run with --no_x86_scrub_rip because we care a lot about how globals are
2 ; accessed in the code model.
3
4 ; RUN: llc < %s -relocation-model=static -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-STATIC
5 ; RUN: llc < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC
6 ; RUN: llc < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC
7 ; RUN: llc < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC
8 ; RUN: llc < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC
9 ; RUN: llc < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC
10
11 ; Generated from this C source:
12 ;
13 ; static int static_data[10];
14 ; int global_data[10] = {1, 2};
15 ; extern int extern_data[10];
16 ;
17 ; int *lea_static_data() { return &static_data[0]; }
18 ; int *lea_global_data() { return &global_data[0]; }
19 ; int *lea_extern_data() { return &extern_data[0]; }
20 ;
21 ; static void static_fn(void) {}
22 ; void global_fn(void) {}
23 ; void extern_fn(void);
24 ;
25 ; typedef void (*void_fn)(void);
26 ; void_fn lea_static_fn() { return &static_fn; }
27 ; void_fn lea_global_fn() { return &global_fn; }
28 ; void_fn lea_extern_fn() { return &extern_fn; }
29
30
31 ; ModuleID = 'model.c'
32 source_filename = "model.c"
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64--linux"
35
36 @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16
37 @static_data = internal global [10 x i32] zeroinitializer, align 16
38 @extern_data = external global [10 x i32], align 16
39
40 define dso_local i32* @lea_static_data() #0 {
41 ; SMALL-STATIC-LABEL: lea_static_data:
42 ; SMALL-STATIC: # %bb.0:
43 ; SMALL-STATIC-NEXT: movl $static_data, %eax
44 ; SMALL-STATIC-NEXT: retq
45 ;
46 ; MEDIUM-STATIC-LABEL: lea_static_data:
47 ; MEDIUM-STATIC: # %bb.0:
48 ; MEDIUM-STATIC-NEXT: movabsq $static_data, %rax
49 ; MEDIUM-STATIC-NEXT: retq
50 ;
51 ; LARGE-STATIC-LABEL: lea_static_data:
52 ; LARGE-STATIC: # %bb.0:
53 ; LARGE-STATIC-NEXT: movabsq $static_data, %rax
54 ; LARGE-STATIC-NEXT: retq
55 ;
56 ; SMALL-PIC-LABEL: lea_static_data:
57 ; SMALL-PIC: # %bb.0:
58 ; SMALL-PIC-NEXT: leaq static_data(%rip), %rax
59 ; SMALL-PIC-NEXT: retq
60 ;
61 ; MEDIUM-PIC-LABEL: lea_static_data:
62 ; MEDIUM-PIC: # %bb.0:
63 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
64 ; MEDIUM-PIC-NEXT: movabsq $static_data@GOTOFF, %rax
65 ; MEDIUM-PIC-NEXT: addq %rcx, %rax
66 ; MEDIUM-PIC-NEXT: retq
67 ;
68 ; LARGE-PIC-LABEL: lea_static_data:
69 ; LARGE-PIC: # %bb.0:
70 ; LARGE-PIC-NEXT: .Ltmp0:
71 ; LARGE-PIC-NEXT: leaq .Ltmp0(%rip), %rcx
72 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp0, %rax
73 ; LARGE-PIC-NEXT: addq %rax, %rcx
74 ; LARGE-PIC-NEXT: movabsq $static_data@GOTOFF, %rax
75 ; LARGE-PIC-NEXT: addq %rcx, %rax
76 ; LARGE-PIC-NEXT: retq
77 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @static_data, i64 0, i64 0)
78 }
79
80 define dso_local i32* @lea_global_data() #0 {
81 ; SMALL-STATIC-LABEL: lea_global_data:
82 ; SMALL-STATIC: # %bb.0:
83 ; SMALL-STATIC-NEXT: movl $global_data, %eax
84 ; SMALL-STATIC-NEXT: retq
85 ;
86 ; MEDIUM-STATIC-LABEL: lea_global_data:
87 ; MEDIUM-STATIC: # %bb.0:
88 ; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax
89 ; MEDIUM-STATIC-NEXT: retq
90 ;
91 ; LARGE-STATIC-LABEL: lea_global_data:
92 ; LARGE-STATIC: # %bb.0:
93 ; LARGE-STATIC-NEXT: movabsq $global_data, %rax
94 ; LARGE-STATIC-NEXT: retq
95 ;
96 ; SMALL-PIC-LABEL: lea_global_data:
97 ; SMALL-PIC: # %bb.0:
98 ; SMALL-PIC-NEXT: leaq global_data(%rip), %rax
99 ; SMALL-PIC-NEXT: retq
100 ;
101 ; MEDIUM-PIC-LABEL: lea_global_data:
102 ; MEDIUM-PIC: # %bb.0:
103 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
104 ; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
105 ; MEDIUM-PIC-NEXT: addq %rcx, %rax
106 ; MEDIUM-PIC-NEXT: retq
107 ;
108 ; LARGE-PIC-LABEL: lea_global_data:
109 ; LARGE-PIC: # %bb.0:
110 ; LARGE-PIC-NEXT: .Ltmp1:
111 ; LARGE-PIC-NEXT: leaq .Ltmp1(%rip), %rcx
112 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp1, %rax
113 ; LARGE-PIC-NEXT: addq %rax, %rcx
114 ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
115 ; LARGE-PIC-NEXT: addq %rcx, %rax
116 ; LARGE-PIC-NEXT: retq
117 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 0)
118 }
119
120 define dso_local i32* @lea_extern_data() #0 {
121 ; SMALL-STATIC-LABEL: lea_extern_data:
122 ; SMALL-STATIC: # %bb.0:
123 ; SMALL-STATIC-NEXT: movl $extern_data, %eax
124 ; SMALL-STATIC-NEXT: retq
125 ;
126 ; MEDIUM-STATIC-LABEL: lea_extern_data:
127 ; MEDIUM-STATIC: # %bb.0:
128 ; MEDIUM-STATIC-NEXT: movabsq $extern_data, %rax
129 ; MEDIUM-STATIC-NEXT: retq
130 ;
131 ; LARGE-STATIC-LABEL: lea_extern_data:
132 ; LARGE-STATIC: # %bb.0:
133 ; LARGE-STATIC-NEXT: movabsq $extern_data, %rax
134 ; LARGE-STATIC-NEXT: retq
135 ;
136 ; SMALL-PIC-LABEL: lea_extern_data:
137 ; SMALL-PIC: # %bb.0:
138 ; SMALL-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
139 ; SMALL-PIC-NEXT: retq
140 ;
141 ; MEDIUM-PIC-LABEL: lea_extern_data:
142 ; MEDIUM-PIC: # %bb.0:
143 ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
144 ; MEDIUM-PIC-NEXT: retq
145 ;
146 ; LARGE-PIC-LABEL: lea_extern_data:
147 ; LARGE-PIC: # %bb.0:
148 ; LARGE-PIC-NEXT: .Ltmp2:
149 ; LARGE-PIC-NEXT: leaq .Ltmp2(%rip), %rax
150 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp2, %rcx
151 ; LARGE-PIC-NEXT: addq %rcx, %rax
152 ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rcx
153 ; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax
154 ; LARGE-PIC-NEXT: retq
155 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 0)
156 }
157
158 define dso_local i32 @load_global_data() #0 {
159 ; SMALL-STATIC-LABEL: load_global_data:
160 ; SMALL-STATIC: # %bb.0:
161 ; SMALL-STATIC-NEXT: movl global_data+8(%rip), %eax
162 ; SMALL-STATIC-NEXT: retq
163 ;
164 ; MEDIUM-STATIC-LABEL: load_global_data:
165 ; MEDIUM-STATIC: # %bb.0:
166 ; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax
167 ; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
168 ; MEDIUM-STATIC-NEXT: retq
169 ;
170 ; LARGE-STATIC-LABEL: load_global_data:
171 ; LARGE-STATIC: # %bb.0:
172 ; LARGE-STATIC-NEXT: movabsq $global_data, %rax
173 ; LARGE-STATIC-NEXT: movl 8(%rax), %eax
174 ; LARGE-STATIC-NEXT: retq
175 ;
176 ; SMALL-PIC-LABEL: load_global_data:
177 ; SMALL-PIC: # %bb.0:
178 ; SMALL-PIC-NEXT: movl global_data+8(%rip), %eax
179 ; SMALL-PIC-NEXT: retq
180 ;
181 ; MEDIUM-PIC-LABEL: load_global_data:
182 ; MEDIUM-PIC: # %bb.0:
183 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
184 ; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rcx
185 ; MEDIUM-PIC-NEXT: movl 8(%rax,%rcx), %eax
186 ; MEDIUM-PIC-NEXT: retq
187 ;
188 ; LARGE-PIC-LABEL: load_global_data:
189 ; LARGE-PIC: # %bb.0:
190 ; LARGE-PIC-NEXT: .Ltmp3:
191 ; LARGE-PIC-NEXT: leaq .Ltmp3(%rip), %rax
192 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp3, %rcx
193 ; LARGE-PIC-NEXT: addq %rcx, %rax
194 ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rcx
195 ; LARGE-PIC-NEXT: movl 8(%rax,%rcx), %eax
196 ; LARGE-PIC-NEXT: retq
197 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 2)
198 ret i32 %rv
199 }
200
201 define dso_local i32 @load_extern_data() #0 {
202 ; SMALL-STATIC-LABEL: load_extern_data:
203 ; SMALL-STATIC: # %bb.0:
204 ; SMALL-STATIC-NEXT: movl extern_data+8(%rip), %eax
205 ; SMALL-STATIC-NEXT: retq
206 ;
207 ; MEDIUM-STATIC-LABEL: load_extern_data:
208 ; MEDIUM-STATIC: # %bb.0:
209 ; MEDIUM-STATIC-NEXT: movabsq $extern_data, %rax
210 ; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
211 ; MEDIUM-STATIC-NEXT: retq
212 ;
213 ; LARGE-STATIC-LABEL: load_extern_data:
214 ; LARGE-STATIC: # %bb.0:
215 ; LARGE-STATIC-NEXT: movabsq $extern_data, %rax
216 ; LARGE-STATIC-NEXT: movl 8(%rax), %eax
217 ; LARGE-STATIC-NEXT: retq
218 ;
219 ; SMALL-PIC-LABEL: load_extern_data:
220 ; SMALL-PIC: # %bb.0:
221 ; SMALL-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
222 ; SMALL-PIC-NEXT: movl 8(%rax), %eax
223 ; SMALL-PIC-NEXT: retq
224 ;
225 ; MEDIUM-PIC-LABEL: load_extern_data:
226 ; MEDIUM-PIC: # %bb.0:
227 ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
228 ; MEDIUM-PIC-NEXT: movl 8(%rax), %eax
229 ; MEDIUM-PIC-NEXT: retq
230 ;
231 ; LARGE-PIC-LABEL: load_extern_data:
232 ; LARGE-PIC: # %bb.0:
233 ; LARGE-PIC-NEXT: .Ltmp4:
234 ; LARGE-PIC-NEXT: leaq .Ltmp4(%rip), %rax
235 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp4, %rcx
236 ; LARGE-PIC-NEXT: addq %rcx, %rax
237 ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rcx
238 ; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax
239 ; LARGE-PIC-NEXT: movl 8(%rax), %eax
240 ; LARGE-PIC-NEXT: retq
241 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 2)
242 ret i32 %rv
243 }
244
245 define dso_local void @global_fn() #0 {
246 ; CHECK-LABEL: global_fn:
247 ; CHECK: # %bb.0:
248 ; CHECK-NEXT: retq
249 ret void
250 }
251
252 define internal void @static_fn() #0 {
253 ; CHECK-LABEL: static_fn:
254 ; CHECK: # %bb.0:
255 ; CHECK-NEXT: retq
256 ret void
257 }
258
259 declare void @extern_fn()
260
261 define dso_local void ()* @lea_static_fn() #0 {
262 ; SMALL-STATIC-LABEL: lea_static_fn:
263 ; SMALL-STATIC: # %bb.0:
264 ; SMALL-STATIC-NEXT: movl $static_fn, %eax
265 ; SMALL-STATIC-NEXT: retq
266 ;
267 ; MEDIUM-STATIC-LABEL: lea_static_fn:
268 ; MEDIUM-STATIC: # %bb.0:
269 ; MEDIUM-STATIC-NEXT: movabsq $static_fn, %rax
270 ; MEDIUM-STATIC-NEXT: retq
271 ;
272 ; LARGE-STATIC-LABEL: lea_static_fn:
273 ; LARGE-STATIC: # %bb.0:
274 ; LARGE-STATIC-NEXT: movabsq $static_fn, %rax
275 ; LARGE-STATIC-NEXT: retq
276 ;
277 ; SMALL-PIC-LABEL: lea_static_fn:
278 ; SMALL-PIC: # %bb.0:
279 ; SMALL-PIC-NEXT: leaq static_fn(%rip), %rax
280 ; SMALL-PIC-NEXT: retq
281 ;
282 ; MEDIUM-PIC-LABEL: lea_static_fn:
283 ; MEDIUM-PIC: # %bb.0:
284 ; MEDIUM-PIC-NEXT: movabsq $static_fn, %rax
285 ; MEDIUM-PIC-NEXT: retq
286 ;
287 ; LARGE-PIC-LABEL: lea_static_fn:
288 ; LARGE-PIC: # %bb.0:
289 ; LARGE-PIC-NEXT: .Ltmp5:
290 ; LARGE-PIC-NEXT: leaq .Ltmp5(%rip), %rcx
291 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp5, %rax
292 ; LARGE-PIC-NEXT: addq %rax, %rcx
293 ; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax
294 ; LARGE-PIC-NEXT: addq %rcx, %rax
295 ; LARGE-PIC-NEXT: retq
296 ret void ()* @static_fn
297 }
298
299 define dso_local void ()* @lea_global_fn() #0 {
300 ; SMALL-STATIC-LABEL: lea_global_fn:
301 ; SMALL-STATIC: # %bb.0:
302 ; SMALL-STATIC-NEXT: movl $global_fn, %eax
303 ; SMALL-STATIC-NEXT: retq
304 ;
305 ; MEDIUM-STATIC-LABEL: lea_global_fn:
306 ; MEDIUM-STATIC: # %bb.0:
307 ; MEDIUM-STATIC-NEXT: movabsq $global_fn, %rax
308 ; MEDIUM-STATIC-NEXT: retq
309 ;
310 ; LARGE-STATIC-LABEL: lea_global_fn:
311 ; LARGE-STATIC: # %bb.0:
312 ; LARGE-STATIC-NEXT: movabsq $global_fn, %rax
313 ; LARGE-STATIC-NEXT: retq
314 ;
315 ; SMALL-PIC-LABEL: lea_global_fn:
316 ; SMALL-PIC: # %bb.0:
317 ; SMALL-PIC-NEXT: leaq global_fn(%rip), %rax
318 ; SMALL-PIC-NEXT: retq
319 ;
320 ; MEDIUM-PIC-LABEL: lea_global_fn:
321 ; MEDIUM-PIC: # %bb.0:
322 ; MEDIUM-PIC-NEXT: movabsq $global_fn, %rax
323 ; MEDIUM-PIC-NEXT: retq
324 ;
325 ; LARGE-PIC-LABEL: lea_global_fn:
326 ; LARGE-PIC: # %bb.0:
327 ; LARGE-PIC-NEXT: .Ltmp6:
328 ; LARGE-PIC-NEXT: leaq .Ltmp6(%rip), %rcx
329 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp6, %rax
330 ; LARGE-PIC-NEXT: addq %rax, %rcx
331 ; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax
332 ; LARGE-PIC-NEXT: addq %rcx, %rax
333 ; LARGE-PIC-NEXT: retq
334 ret void ()* @global_fn
335 }
336
337 define dso_local void ()* @lea_extern_fn() #0 {
338 ; SMALL-STATIC-LABEL: lea_extern_fn:
339 ; SMALL-STATIC: # %bb.0:
340 ; SMALL-STATIC-NEXT: movl $extern_fn, %eax
341 ; SMALL-STATIC-NEXT: retq
342 ;
343 ; MEDIUM-STATIC-LABEL: lea_extern_fn:
344 ; MEDIUM-STATIC: # %bb.0:
345 ; MEDIUM-STATIC-NEXT: movabsq $extern_fn, %rax
346 ; MEDIUM-STATIC-NEXT: retq
347 ;
348 ; LARGE-STATIC-LABEL: lea_extern_fn:
349 ; LARGE-STATIC: # %bb.0:
350 ; LARGE-STATIC-NEXT: movabsq $extern_fn, %rax
351 ; LARGE-STATIC-NEXT: retq
352 ;
353 ; SMALL-PIC-LABEL: lea_extern_fn:
354 ; SMALL-PIC: # %bb.0:
355 ; SMALL-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax
356 ; SMALL-PIC-NEXT: retq
357 ;
358 ; MEDIUM-PIC-LABEL: lea_extern_fn:
359 ; MEDIUM-PIC: # %bb.0:
360 ; MEDIUM-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax
361 ; MEDIUM-PIC-NEXT: retq
362 ;
363 ; LARGE-PIC-LABEL: lea_extern_fn:
364 ; LARGE-PIC: # %bb.0:
365 ; LARGE-PIC-NEXT: .Ltmp7:
366 ; LARGE-PIC-NEXT: leaq .Ltmp7(%rip), %rax
367 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp7, %rcx
368 ; LARGE-PIC-NEXT: addq %rcx, %rax
369 ; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rcx
370 ; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax
371 ; LARGE-PIC-NEXT: retq
372 ret void ()* @extern_fn
373 }
374
375 attributes #0 = { noinline nounwind uwtable }
376
377 !llvm.module.flags = !{!0, !1, !2}
378 !llvm.ident = !{!3}
379
380 !0 = !{i32 1, !"wchar_size", i32 4}
381 !1 = !{i32 7, !"PIC Level", i32 2}
382 !2 = !{i32 7, !"PIE Level", i32 2}
383 !3 = !{!"clang version 7.0.0 "}
None ; RUN: llc -fast-isel-sink-local-values -fast-isel -O0 -code-model=large -mcpu=generic -mtriple=x86_64-linux -relocation-model=static < %s | FileCheck %s
0 ; RUN: llc -fast-isel-sink-local-values -fast-isel -O0 -code-model=large -mcpu=generic -mtriple=x86_64-apple-darwin10 -relocation-model=pic < %s | FileCheck %s
11
22 ; Check that fast-isel cleans up when it fails to lower a call instruction.
33 define void @fastiselcall() {
88 ; FastISel's local value code was dead, so it's gone.
99 ; CHECK-NOT: movl $42,
1010 ; SDag-ISel's arg mov:
11 ; CHECK: movabsq $targetfn, %[[REG:[^ ]*]]
11 ; CHECK: movabsq $_targetfn, %[[REG:[^ ]*]]
1212 ; CHECK: movl $42, %edi
1313 ; CHECK: callq *%[[REG]]
1414
1515 ;
1616 ; LARGE-LABEL: constpool_float:
1717 ; LARGE: ## %bb.0:
18 ; LARGE-NEXT: Ltmp0:
19 ; LARGE-NEXT: leaq {{.*}}(%rip), %rax
20 ; LARGE-NEXT: movabsq $__GLOBAL_OFFSET_TABLE_-Ltmp0, %rcx
21 ; LARGE-NEXT: addq %rcx, %rax
22 ; LARGE-NEXT: movabsq $LCPI0_0@GOTOFF, %rax
18 ; LARGE-NEXT: movabsq $LCPI0_0, %rax
2319 ; LARGE-NEXT: addss (%rax), %xmm0
2420 ; LARGE-NEXT: retq
2521 ;
3127 ;
3228 ; LARGE_AVX-LABEL: constpool_float:
3329 ; LARGE_AVX: ## %bb.0:
34 ; LARGE_AVX-NEXT: Ltmp0:
35 ; LARGE_AVX-NEXT: leaq {{.*}}(%rip), %rax
36 ; LARGE_AVX-NEXT: movabsq $__GLOBAL_OFFSET_TABLE_-Ltmp0, %rcx
37 ; LARGE_AVX-NEXT: addq %rcx, %rax
38 ; LARGE_AVX-NEXT: movabsq $LCPI0_0@GOTOFF, %rax
30 ; LARGE_AVX-NEXT: movabsq $LCPI0_0, %rax
3931 ; LARGE_AVX-NEXT: vaddss (%rax), %xmm0, %xmm0
4032 ; LARGE_AVX-NEXT: retq
4133
5244 ;
5345 ; LARGE-LABEL: constpool_double:
5446 ; LARGE: ## %bb.0:
55 ; LARGE-NEXT: Ltmp1:
56 ; LARGE-NEXT: leaq {{.*}}(%rip), %rax
57 ; LARGE-NEXT: movabsq $__GLOBAL_OFFSET_TABLE_-Ltmp1, %rcx
58 ; LARGE-NEXT: addq %rcx, %rax
59 ; LARGE-NEXT: movabsq $LCPI1_0@GOTOFF, %rax
47 ; LARGE-NEXT: movabsq $LCPI1_0, %rax
6048 ; LARGE-NEXT: addsd (%rax), %xmm0
6149 ; LARGE-NEXT: retq
6250 ;
6856 ;
6957 ; LARGE_AVX-LABEL: constpool_double:
7058 ; LARGE_AVX: ## %bb.0:
71 ; LARGE_AVX-NEXT: Ltmp1:
72 ; LARGE_AVX-NEXT: leaq {{.*}}(%rip), %rax
73 ; LARGE_AVX-NEXT: movabsq $__GLOBAL_OFFSET_TABLE_-Ltmp1, %rcx
74 ; LARGE_AVX-NEXT: addq %rcx, %rax
75 ; LARGE_AVX-NEXT: movabsq $LCPI1_0@GOTOFF, %rax
59 ; LARGE_AVX-NEXT: movabsq $LCPI1_0, %rax
7660 ; LARGE_AVX-NEXT: vaddsd (%rax), %xmm0, %xmm0
7761 ; LARGE_AVX-NEXT: retq
7862
None ; RUN: llc < %s -stack-symbol-ordering=0 -tailcallopt -relocation-model=static -code-model=medium -stack-alignment=8 -mtriple=x86_64-linux-gnu -mcpu=opteron | FileCheck %s
0 ; RUN: llc < %s -stack-symbol-ordering=0 -tailcallopt -code-model=medium -stack-alignment=8 -mtriple=x86_64-linux-gnu -mcpu=opteron | FileCheck %s
11
22 ; Check the HiPE calling convention works (x86-64)
33
None ; REQUIRES: cxx-shared-library, system-linux
0 ; REQUIRES: cxx-shared-library
11 ; RUN: %lli -relocation-model=pic -code-model=large %s
2 ; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm
2 ; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm
33 declare i8* @__cxa_allocate_exception(i64)
44 declare void @__cxa_throw(i8*, i8*, i8*)
55 declare i32 @__gxx_personality_v0(...)
1414 unreachable
1515 }
1616
17 ; Make an internal function so we exercise R_X86_64_GOTOFF64 relocations.
18 define internal dso_local void @use_gotoff() {
19 ret void
20 }
21
2217 define i32 @main() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2318 entry:
24 call void @use_gotoff()
2519 invoke void @throwException()
2620 to label %try.cont unwind label %lpad
2721
109109 asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r'{{[-0-9]+}}(%\1{{[sb]}}p)\2', asm)
110110 # Generically match the stack offset of a memory operand.
111111 asm = SCRUB_X86_SP_RE.sub(r'{{[0-9]+}}(%\1)', asm)
112 if getattr(args, 'x86_scrub_rip', False):
113 # Generically match a RIP-relative memory operand.
114 asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
112 # Generically match a RIP-relative memory operand.
113 asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
115114 # Generically match a LCP symbol.
116115 asm = SCRUB_X86_LCP_RE.sub(r'{{\.LCPI.*}}', asm)
117116 if getattr(args, 'extra_scrub', False):
2929 parser.add_argument(
3030 '--extra_scrub', action='store_true',
3131 help='Always use additional regex to further reduce diffs between various subtargets')
32 parser.add_argument(
33 '--x86_scrub_rip', action='store_true', default=True,
34 help='Use more regex for x86 matching to reduce diffs between various subtargets')
35 parser.add_argument(
36 '--no_x86_scrub_rip', action='store_false', dest='x86_scrub_rip')
3732 parser.add_argument('tests', nargs='+')
3833 args = parser.parse_args()
3934