1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64 3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-pc-win32 -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECKWIN64 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdefine i32 @one32_nooptsize() { 6*9880d681SAndroid Build Coastguard Workerentry: 7*9880d681SAndroid Build Coastguard Worker ret i32 1 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; When not optimizing for size, use mov. 10*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32_nooptsize: 11*9880d681SAndroid Build Coastguard Worker; CHECK32: movl $1, %eax 12*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 13*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32_nooptsize: 14*9880d681SAndroid Build Coastguard Worker; CHECK64: movl $1, %eax 15*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT: retq 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdefine i32 @one32() optsize { 19*9880d681SAndroid Build Coastguard Workerentry: 20*9880d681SAndroid Build Coastguard Worker ret i32 1 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32: 23*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 24*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: incl %eax 25*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker; FIXME: Figure out the best approach in 64-bit mode. 28*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32: 29*9880d681SAndroid Build Coastguard Worker; CHECK64: movl $1, %eax 30*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT: retq 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerdefine i32 @one32_minsize() minsize { 34*9880d681SAndroid Build Coastguard Workerentry: 35*9880d681SAndroid Build Coastguard Worker ret i32 1 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; On 32-bit, xor-inc is preferred over push-pop. 38*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one32_minsize: 39*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 40*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: incl %eax 41*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; On 64-bit we don't do xor-inc yet, so push-pop it is. Note that we have to 44*9880d681SAndroid Build Coastguard Worker; pop into a 64-bit register even when we just need 32 bits. 45*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one32_minsize: 46*9880d681SAndroid Build Coastguard Worker; CHECK64: pushq $1 47*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset 8 48*9880d681SAndroid Build Coastguard Worker; CHECK64: popq %rax 49*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset -8 50*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT: retq 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker; On Win64 we can't adjust the stack unless there's a frame pointer. 53*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-LABEL: one32_minsize: 54*9880d681SAndroid Build Coastguard Worker; CHECKWIN64: movl $1, %eax 55*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-NEXT: retq 56*9880d681SAndroid Build Coastguard Worker} 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerdefine i32 @pr26023() minsize { 59*9880d681SAndroid Build Coastguard Workerentry: 60*9880d681SAndroid Build Coastguard Worker %x = alloca [120 x i8] 61*9880d681SAndroid Build Coastguard Worker %0 = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 0 62*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "", "imr,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0) 63*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 119 64*9880d681SAndroid Build Coastguard Worker store volatile i8 -2, i8* %arrayidx 65*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(i32 5) 66*9880d681SAndroid Build Coastguard Worker %1 = load volatile i8, i8* %arrayidx 67*9880d681SAndroid Build Coastguard Worker %conv = sext i8 %1 to i32 68*9880d681SAndroid Build Coastguard Worker ret i32 %conv 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; The function writes to the redzone, so push/pop cannot be used. 71*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: pr26023: 72*9880d681SAndroid Build Coastguard Worker; CHECK64: movl $5, %ecx 73*9880d681SAndroid Build Coastguard Worker; CHECK64: retq 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; 32-bit X86 doesn't have a redzone. 76*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: pr26023: 77*9880d681SAndroid Build Coastguard Worker; CHECK32: pushl $5 78*9880d681SAndroid Build Coastguard Worker; CHECK32: popl %ecx 79*9880d681SAndroid Build Coastguard Worker; CHECK32: retl 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdefine i64 @one64_minsize() minsize { 84*9880d681SAndroid Build Coastguard Workerentry: 85*9880d681SAndroid Build Coastguard Worker ret i64 1 86*9880d681SAndroid Build Coastguard Worker; On 64-bit we don't do xor-inc yet, so push-pop it is. 87*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: one64_minsize: 88*9880d681SAndroid Build Coastguard Worker; CHECK64: pushq $1 89*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset 8 90*9880d681SAndroid Build Coastguard Worker; CHECK64: popq %rax 91*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset -8 92*9880d681SAndroid Build Coastguard Worker; CHECK64-NEXT: retq 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker; On Win64 we can't adjust the stack unless there's a frame pointer. 95*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-LABEL: one64_minsize: 96*9880d681SAndroid Build Coastguard Worker; CHECKWIN64: movl $1, %eax 97*9880d681SAndroid Build Coastguard Worker; CHECKWIN64-NEXT: retq 98*9880d681SAndroid Build Coastguard Worker} 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_one32() optsize { 101*9880d681SAndroid Build Coastguard Workerentry: 102*9880d681SAndroid Build Coastguard Worker ret i32 -1 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one32: 105*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 106*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %eax 107*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_one32_minsize() minsize { 111*9880d681SAndroid Build Coastguard Workerentry: 112*9880d681SAndroid Build Coastguard Worker ret i32 -1 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; xor-dec is preferred over push-pop. 115*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one32_minsize: 116*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 117*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %eax 118*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 119*9880d681SAndroid Build Coastguard Worker} 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerdefine i16 @one16() optsize { 122*9880d681SAndroid Build Coastguard Workerentry: 123*9880d681SAndroid Build Coastguard Worker ret i16 1 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: one16: 126*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 127*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: incl %eax 128*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: # kill 129*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 130*9880d681SAndroid Build Coastguard Worker} 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Workerdefine i16 @minus_one16() optsize { 133*9880d681SAndroid Build Coastguard Workerentry: 134*9880d681SAndroid Build Coastguard Worker ret i16 -1 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_one16: 137*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 138*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %eax 139*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: # kill 140*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: retl 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Workerdefine i32 @minus_five32() minsize { 144*9880d681SAndroid Build Coastguard Workerentry: 145*9880d681SAndroid Build Coastguard Worker ret i32 -5 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: minus_five32: 148*9880d681SAndroid Build Coastguard Worker; CHECK32: pushl $-5 149*9880d681SAndroid Build Coastguard Worker; CHECK32: popl %eax 150*9880d681SAndroid Build Coastguard Worker; CHECK32: retl 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerdefine i64 @minus_five64() minsize { 154*9880d681SAndroid Build Coastguard Workerentry: 155*9880d681SAndroid Build Coastguard Worker ret i64 -5 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker; CHECK64-LABEL: minus_five64: 158*9880d681SAndroid Build Coastguard Worker; CHECK64: pushq $-5 159*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset 8 160*9880d681SAndroid Build Coastguard Worker; CHECK64: popq %rax 161*9880d681SAndroid Build Coastguard Worker; CHECK64: .cfi_adjust_cfa_offset -8 162*9880d681SAndroid Build Coastguard Worker; CHECK64: retq 163*9880d681SAndroid Build Coastguard Worker} 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerdefine i32 @rematerialize_minus_one() optsize { 166*9880d681SAndroid Build Coastguard Workerentry: 167*9880d681SAndroid Build Coastguard Worker ; Materialize -1 (thiscall forces it into %ecx). 168*9880d681SAndroid Build Coastguard Worker tail call x86_thiscallcc void @f(i32 -1) 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker ; Clobber all registers except %esp, leaving nowhere to store the -1 besides 171*9880d681SAndroid Build Coastguard Worker ; spilling it to the stack. 172*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"() 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker ; -1 should be re-materialized here instead of getting spilled above. 175*9880d681SAndroid Build Coastguard Worker ret i32 -1 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: rematerialize_minus_one 178*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %ecx, %ecx 179*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %ecx 180*9880d681SAndroid Build Coastguard Worker; CHECK32: calll 181*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %eax, %eax 182*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %eax 183*9880d681SAndroid Build Coastguard Worker; CHECK32-NOT: %eax 184*9880d681SAndroid Build Coastguard Worker; CHECK32: retl 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Workerdefine i32 @rematerialize_minus_one_eflags(i32 %x) optsize { 188*9880d681SAndroid Build Coastguard Workerentry: 189*9880d681SAndroid Build Coastguard Worker ; Materialize -1 (thiscall forces it into %ecx). 190*9880d681SAndroid Build Coastguard Worker tail call x86_thiscallcc void @f(i32 -1) 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker ; Clobber all registers except %esp, leaving nowhere to store the -1 besides 193*9880d681SAndroid Build Coastguard Worker ; spilling it to the stack. 194*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"() 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker ; Define eflags. 197*9880d681SAndroid Build Coastguard Worker %a = icmp ne i32 %x, 123 198*9880d681SAndroid Build Coastguard Worker %b = zext i1 %a to i32 199*9880d681SAndroid Build Coastguard Worker ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags. 200*9880d681SAndroid Build Coastguard Worker ; It must therefore not use the xor-dec lowering. 201*9880d681SAndroid Build Coastguard Worker %c = select i1 %a, i32 %b, i32 -1 202*9880d681SAndroid Build Coastguard Worker ret i32 %c 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; CHECK32-LABEL: rematerialize_minus_one_eflags 205*9880d681SAndroid Build Coastguard Worker; CHECK32: xorl %ecx, %ecx 206*9880d681SAndroid Build Coastguard Worker; CHECK32-NEXT: decl %ecx 207*9880d681SAndroid Build Coastguard Worker; CHECK32: calll 208*9880d681SAndroid Build Coastguard Worker; CHECK32: cmpl 209*9880d681SAndroid Build Coastguard Worker; CHECK32: setne 210*9880d681SAndroid Build Coastguard Worker; CHECK32-NOT: xorl 211*9880d681SAndroid Build Coastguard Worker; CHECK32: movl $-1 212*9880d681SAndroid Build Coastguard Worker; CHECK32: cmov 213*9880d681SAndroid Build Coastguard Worker; CHECK32: retl 214*9880d681SAndroid Build Coastguard Worker} 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Workerdeclare x86_thiscallcc void @f(i32) 217