llvm.org GIT mirror llvm / f1bdd64
Merging r354756: ------------------------------------------------------------------------ r354756 | ctopper | 2019-02-24 20:33:37 +0100 (Sun, 24 Feb 2019) | 36 lines [X86] Fix tls variable lowering issue with large code model Summary: The problem here is the lowering for tls variable. Below is the DAG for the code. SelectionDAG has 11 nodes: t0: ch = EntryToken t8: i64,ch = load<(load 8 from `i8 addrspace(257)* null`, addrspace 257)> t0, Constant:i64<0>, undef:i64 t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10] t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64 t12: i64 = add t8, t11 t4: i32,ch = load<(dereferenceable load 4 from @x)> t0, t12, undef:i64 t6: ch = CopyToReg t0, Register:i32 %0, t4 And when mcmodel is large, below instruction can NOT be folded. t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10] t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64 So "t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64" is lowered to " Morphed node: t11: i64,ch = MOV64rm<Mem:(load 8 from got)> t10, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i32 $noreg, t0" When llvm start to lower "t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10]", it fails. The patch is to fold the load and X86ISD::WrapperRIP. Fixes PR26906 Patch by LuoYuanke Reviewers: craig.topper, rnk, annita.zhang, wxiao3 Reviewed By: rnk Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58336 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@354857 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 9 months ago
2 changed file(s) with 80 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
11371137 if (AM.hasSymbolicDisplacement())
11381138 return true;
11391139
1140 bool IsRIPRelTLS = false;
11401141 bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP;
1141
1142 // We can't use an addressing mode in the 64-bit large code model. In the
1143 // medium code model, we use can use an mode when RIP wrappers are present.
1144 // That signifies access to globals that are known to be "near", such as the
1145 // GOT itself.
1142 if (IsRIPRel) {
1143 SDValue Val = N.getOperand(0);
1144 if (Val.getOpcode() == ISD::TargetGlobalTLSAddress)
1145 IsRIPRelTLS = true;
1146 }
1147
1148 // We can't use an addressing mode in the 64-bit large code model.
1149 // Global TLS addressing is an exception. In the medium code model,
1150 // we use can use a mode when RIP wrappers are present.
1151 // That signifies access to globals that are known to be "near",
1152 // such as the GOT itself.
11461153 CodeModel::Model M = TM.getCodeModel();
11471154 if (Subtarget->is64Bit() &&
1148 (M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel)))
1155 ((M == CodeModel::Large && !IsRIPRelTLS) ||
1156 (M == CodeModel::Medium && !IsRIPRel)))
11491157 return true;
11501158
11511159 // Base and index reg must be 0 in order to use %rip as base.
3636 @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
3737 @static_data = internal global [10 x i32] zeroinitializer, align 16
3838 @extern_data = external global [10 x i32], align 16
39 @thread_data = external thread_local global i32, align 4
40
3941
4042 define dso_local i32* @lea_static_data() #0 {
4143 ; SMALL-STATIC-LABEL: lea_static_data:
372374 ret void ()* @extern_fn
373375 }
374376
377 ; FIXME: The result is same for small, medium and large model, because we
378 ; specify pie option in the test case. And the type of tls is initial exec tls.
379 ; For pic code. The large model code for pic tls should be emitted as below.
380
381 ; .L3:
382 ; leaq .L3(%rip), %rbx
383 ; movabsq $_GLOBAL_OFFSET_TABLE_-.L3, %r11
384 ; addq %r11, %rbx
385 ; leaq thread_data@TLSGD(%rip), %rdi
386 ; movabsq $__tls_get_addr@PLTOFF, %rax
387 ; addq %rbx, %rax
388 ; call *%rax
389 ; movl (%rax), %eax
390
391 ; The medium and small model code for pic tls should be emitted as below.
392 ; data16
393 ; leaq thread_data@TLSGD(%rip), %rdi
394 ; data16
395 ; data16
396 ; rex64
397 ; callq __tls_get_addr@PLT
398 ; movl (%rax), %eax
399
400 define dso_local i32 @load_thread_data() #0 {
401 ; SMALL-STATIC-LABEL: load_thread_data:
402 ; SMALL-STATIC: # %bb.0:
403 ; SMALL-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
404 ; SMALL-STATIC-NEXT: movl %fs:(%rax), %eax
405 ; SMALL-STATIC-NEXT: retq
406 ;
407 ; MEDIUM-STATIC-LABEL: load_thread_data:
408 ; MEDIUM-STATIC: # %bb.0:
409 ; MEDIUM-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
410 ; MEDIUM-STATIC-NEXT: movl %fs:(%rax), %eax
411 ; MEDIUM-STATIC-NEXT: retq
412 ;
413 ; LARGE-STATIC-LABEL: load_thread_data:
414 ; LARGE-STATIC: # %bb.0:
415 ; LARGE-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
416 ; LARGE-STATIC-NEXT: movl %fs:(%rax), %eax
417 ; LARGE-STATIC-NEXT: retq
418 ;
419 ; SMALL-PIC-LABEL: load_thread_data:
420 ; SMALL-PIC: # %bb.0:
421 ; SMALL-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
422 ; SMALL-PIC-NEXT: movl %fs:(%rax), %eax
423 ; SMALL-PIC-NEXT: retq
424 ;
425 ; MEDIUM-PIC-LABEL: load_thread_data:
426 ; MEDIUM-PIC: # %bb.0:
427 ; MEDIUM-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
428 ; MEDIUM-PIC-NEXT: movl %fs:(%rax), %eax
429 ; MEDIUM-PIC-NEXT: retq
430 ;
431 ; LARGE-PIC-LABEL: load_thread_data:
432 ; LARGE-PIC: # %bb.0:
433 ; LARGE-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
434 ; LARGE-PIC-NEXT: movl %fs:(%rax), %eax
435 ; LARGE-PIC-NEXT: retq
436 ;
437 %1 = load i32, i32* @thread_data, align 4
438 ret i32 %1
439 }
440
375441 attributes #0 = { noinline nounwind uwtable }
376442
377443 !llvm.module.flags = !{!0, !1, !2}