1; RUN: llc < %s -fast-isel -mtriple=i386-apple-darwin -mcpu=generic | FileCheck %s 2; RUN: llc < %s -fast-isel -mtriple=i386-apple-darwin -mcpu=atom | FileCheck -check-prefix=ATOM %s 3; RUN: llc < %s -fast-isel -fast-isel-abort=3 -mtriple=x86_64 | FileCheck -check-prefix=ELF64 %s 4 5@src = external dso_preemptable global i32 6 7; rdar://6653118 8define i32 @loadgv() nounwind { 9entry: 10 %0 = load i32, ptr @src, align 4 11 %1 = load i32, ptr @src, align 4 12 %2 = add i32 %0, %1 13 store i32 %2, ptr @src 14 ret i32 %2 15; This should fold one of the loads into the add. 16; CHECK-LABEL: loadgv: 17; CHECK: movl L_src$non_lazy_ptr, %eax 18; CHECK: movl (%eax), %eax 19; CHECK: movl L_src$non_lazy_ptr, %ecx 20; CHECK: addl (%ecx), %eax 21; CHECK: movl L_src$non_lazy_ptr, %ecx 22; CHECK: movl %eax, (%ecx) 23; CHECK: ret 24 25; ATOM: loadgv: 26; ATOM: movl L_src$non_lazy_ptr, %eax 27; ATOM: movl (%eax), %eax 28; ATOM: movl L_src$non_lazy_ptr, %ecx 29; ATOM: addl (%ecx), %eax 30; ATOM: movl L_src$non_lazy_ptr, %ecx 31; ATOM: movl %eax, (%ecx) 32; ATOM: ret 33 34;; dso_preemptable src is loaded via GOT indirection. 35; ELF64-LABEL: loadgv: 36; ELF64: movq src@GOTPCREL(%rip), %rax 37; ELF64-NEXT: movl (%rax), %eax 38; ELF64-NEXT: movq src@GOTPCREL(%rip), %rcx 39; ELF64-NEXT: addl (%rcx), %eax 40; ELF64-NEXT: movq src@GOTPCREL(%rip), %rcx 41; ELF64-NEXT: movl %eax, (%rcx) 42; ELF64-NEXT: retq 43 44} 45 46%stuff = type { ptr } 47@LotsStuff = external constant [4 x ptr] 48 49define void @t(ptr %this) nounwind { 50entry: 51 store ptr getelementptr ([4 x ptr], ptr @LotsStuff, i32 0, i32 2), ptr null, align 4 52 ret void 53; CHECK: _t: 54; CHECK: xorl %eax, %eax 55; CHECK: movl L_LotsStuff$non_lazy_ptr, %ecx 56 57; ATOM: _t: 58; ATOM: movl L_LotsStuff$non_lazy_ptr, %e{{..}} 59; ATOM: xorl %e{{..}}, %e{{..}} 60 61} 62