1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=generic -mtriple=i386-apple-darwin -no-integrated-as | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; There should be no stack manipulations between the inline asm and ret. 4*9880d681SAndroid Build Coastguard Worker; CHECK: test1 5*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 6*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 7*9880d681SAndroid Build Coastguard Workerdefine x86_fp80 @test1() { 8*9880d681SAndroid Build Coastguard Worker %tmp85 = call x86_fp80 asm sideeffect "fld0", "={st(0)}"() 9*9880d681SAndroid Build Coastguard Worker ret x86_fp80 %tmp85 10*9880d681SAndroid Build Coastguard Worker} 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker; CHECK: test2 13*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 15*9880d681SAndroid Build Coastguard Workerdefine double @test2() { 16*9880d681SAndroid Build Coastguard Worker %tmp85 = call double asm sideeffect "fld0", "={st(0)}"() 17*9880d681SAndroid Build Coastguard Worker ret double %tmp85 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Setting up argument in st(0) should be a single fld. 21*9880d681SAndroid Build Coastguard Worker; CHECK: test3 22*9880d681SAndroid Build Coastguard Worker; CHECK: fld 23*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: InlineAsm Start 24*9880d681SAndroid Build Coastguard Worker; Asm consumes stack, nothing should be popped. 25*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 26*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 27*9880d681SAndroid Build Coastguard Worker; CHECK: ret 28*9880d681SAndroid Build Coastguard Workerdefine void @test3(x86_fp80 %X) { 29*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "frob ", "{st(0)},~{st},~{dirflag},~{fpsr},~{flags}"( x86_fp80 %X) 30*9880d681SAndroid Build Coastguard Worker ret void 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; CHECK: test4 34*9880d681SAndroid Build Coastguard Worker; CHECK: fld 35*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: InlineAsm Start 36*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 38*9880d681SAndroid Build Coastguard Worker; CHECK: ret 39*9880d681SAndroid Build Coastguard Workerdefine void @test4(double %X) { 40*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "frob ", "{st(0)},~{st},~{dirflag},~{fpsr},~{flags}"( double %X) 41*9880d681SAndroid Build Coastguard Worker ret void 42*9880d681SAndroid Build Coastguard Worker} 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker; Same as test3/4, but using value from fadd. 45*9880d681SAndroid Build Coastguard Worker; The fadd can be done in xmm or x87 regs - we don't test that. 46*9880d681SAndroid Build Coastguard Worker; CHECK: test5 47*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 48*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 49*9880d681SAndroid Build Coastguard Worker; CHECK: ret 50*9880d681SAndroid Build Coastguard Workerdefine void @test5(double %X) { 51*9880d681SAndroid Build Coastguard Worker %Y = fadd double %X, 123.0 52*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "frob ", "{st(0)},~{st},~{dirflag},~{fpsr},~{flags}"( double %Y) 53*9880d681SAndroid Build Coastguard Worker ret void 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; CHECK: test6 57*9880d681SAndroid Build Coastguard Workerdefine void @test6(double %A, double %B, double %C, 58*9880d681SAndroid Build Coastguard Worker double %D, double %E) nounwind { 59*9880d681SAndroid Build Coastguard Workerentry: 60*9880d681SAndroid Build Coastguard Worker; Uses the same value twice, should have one fstp after the asm. 61*9880d681SAndroid Build Coastguard Worker; CHECK: foo 62*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fstp 64*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 65*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "foo $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %A, double %A ) nounwind 66*9880d681SAndroid Build Coastguard Worker; Uses two different values, should be in st(0)/st(1) and both be popped. 67*9880d681SAndroid Build Coastguard Worker; CHECK: bar 68*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fstp 70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fstp 71*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "bar $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %B, double %C ) nounwind 72*9880d681SAndroid Build Coastguard Worker; Uses two different values, one of which isn't killed in this asm, it 73*9880d681SAndroid Build Coastguard Worker; should not be popped after the asm. 74*9880d681SAndroid Build Coastguard Worker; CHECK: baz 75*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fstp 77*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 78*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "baz $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %D, double %E ) nounwind 79*9880d681SAndroid Build Coastguard Worker; This is the last use of %D, so it should be popped after. 80*9880d681SAndroid Build Coastguard Worker; CHECK: baz 81*9880d681SAndroid Build Coastguard Worker; CHECK: InlineAsm End 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fstp 83*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 84*9880d681SAndroid Build Coastguard Worker; CHECK: ret 85*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "baz $0", "f,~{dirflag},~{fpsr},~{flags}"( double %D ) nounwind 86*9880d681SAndroid Build Coastguard Worker ret void 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; PR4185 90*9880d681SAndroid Build Coastguard Worker; Passing a non-killed value to asm in {st}. 91*9880d681SAndroid Build Coastguard Worker; Make sure it is duped before. 92*9880d681SAndroid Build Coastguard Worker; asm kills st(0), so we shouldn't pop anything 93*9880d681SAndroid Build Coastguard Worker; CHECK: testPR4185 94*9880d681SAndroid Build Coastguard Worker; CHECK: fld %st(0) 95*9880d681SAndroid Build Coastguard Worker; CHECK: fistpl 96*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 97*9880d681SAndroid Build Coastguard Worker; CHECK: fistpl 98*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 99*9880d681SAndroid Build Coastguard Worker; CHECK: ret 100*9880d681SAndroid Build Coastguard Worker; A valid alternative would be to remat the constant pool load before each 101*9880d681SAndroid Build Coastguard Worker; inline asm. 102*9880d681SAndroid Build Coastguard Workerdefine void @testPR4185() { 103*9880d681SAndroid Build Coastguard Workerreturn: 104*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistpl $0", "{st},~{st}"(double 1.000000e+06) 105*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistpl $0", "{st},~{st}"(double 1.000000e+06) 106*9880d681SAndroid Build Coastguard Worker ret void 107*9880d681SAndroid Build Coastguard Worker} 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker; Passing a non-killed value through asm in {st}. 110*9880d681SAndroid Build Coastguard Worker; Make sure it is not duped before. 111*9880d681SAndroid Build Coastguard Worker; Second asm kills st(0), so we shouldn't pop anything 112*9880d681SAndroid Build Coastguard Worker; CHECK: testPR4185b 113*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fld %st(0) 114*9880d681SAndroid Build Coastguard Worker; CHECK: fistl 115*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 116*9880d681SAndroid Build Coastguard Worker; CHECK: fistpl 117*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 118*9880d681SAndroid Build Coastguard Worker; CHECK: ret 119*9880d681SAndroid Build Coastguard Worker; A valid alternative would be to remat the constant pool load before each 120*9880d681SAndroid Build Coastguard Worker; inline asm. 121*9880d681SAndroid Build Coastguard Workerdefine void @testPR4185b() { 122*9880d681SAndroid Build Coastguard Workerreturn: 123*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistl $0", "{st}"(double 1.000000e+06) 124*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistpl $0", "{st},~{st}"(double 1.000000e+06) 125*9880d681SAndroid Build Coastguard Worker ret void 126*9880d681SAndroid Build Coastguard Worker} 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker; PR4459 129*9880d681SAndroid Build Coastguard Worker; The return value from ceil must be duped before being consumed by asm. 130*9880d681SAndroid Build Coastguard Worker; CHECK: testPR4459 131*9880d681SAndroid Build Coastguard Worker; CHECK: ceil 132*9880d681SAndroid Build Coastguard Worker; CHECK: fld %st(0) 133*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fxch 134*9880d681SAndroid Build Coastguard Worker; CHECK: fistpl 135*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fxch 136*9880d681SAndroid Build Coastguard Worker; CHECK: fstpt 137*9880d681SAndroid Build Coastguard Worker; CHECK: test 138*9880d681SAndroid Build Coastguard Workerdefine void @testPR4459(x86_fp80 %a) { 139*9880d681SAndroid Build Coastguard Workerentry: 140*9880d681SAndroid Build Coastguard Worker %0 = call x86_fp80 @ceil(x86_fp80 %a) 141*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistpl $0", "{st},~{st}"( x86_fp80 %0) 142*9880d681SAndroid Build Coastguard Worker call void @test3(x86_fp80 %0 ) 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Workerdeclare x86_fp80 @ceil(x86_fp80) 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker; PR4484 148*9880d681SAndroid Build Coastguard Worker; test1 leaves a value on the stack that is needed after the asm. 149*9880d681SAndroid Build Coastguard Worker; CHECK: testPR4484 150*9880d681SAndroid Build Coastguard Worker; CHECK: calll _test1 151*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 152*9880d681SAndroid Build Coastguard Worker; Load %a from stack after ceil 153*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 154*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fxch 155*9880d681SAndroid Build Coastguard Worker; CHECK: fistpl 156*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 157*9880d681SAndroid Build Coastguard Worker; Set up call to test. 158*9880d681SAndroid Build Coastguard Worker; CHECK: fstpt 159*9880d681SAndroid Build Coastguard Worker; CHECK: test 160*9880d681SAndroid Build Coastguard Workerdefine void @testPR4484(x86_fp80 %a) { 161*9880d681SAndroid Build Coastguard Workerentry: 162*9880d681SAndroid Build Coastguard Worker %0 = call x86_fp80 @test1() 163*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fistpl $0", "{st},~{st}"(x86_fp80 %a) 164*9880d681SAndroid Build Coastguard Worker call void @test3(x86_fp80 %0) 165*9880d681SAndroid Build Coastguard Worker ret void 166*9880d681SAndroid Build Coastguard Worker} 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker; PR4485 169*9880d681SAndroid Build Coastguard Worker; CHECK: testPR4485 170*9880d681SAndroid Build Coastguard Workerdefine void @testPR4485(x86_fp80* %a) { 171*9880d681SAndroid Build Coastguard Workerentry: 172*9880d681SAndroid Build Coastguard Worker %0 = load x86_fp80, x86_fp80* %a, align 16 173*9880d681SAndroid Build Coastguard Worker %1 = fmul x86_fp80 %0, 0xK4006B400000000000000 174*9880d681SAndroid Build Coastguard Worker %2 = fmul x86_fp80 %1, 0xK4012F424000000000000 175*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fistpl $0", "{st},~{st}"(x86_fp80 %2) 176*9880d681SAndroid Build Coastguard Worker %3 = load x86_fp80, x86_fp80* %a, align 16 177*9880d681SAndroid Build Coastguard Worker %4 = fmul x86_fp80 %3, 0xK4006B400000000000000 178*9880d681SAndroid Build Coastguard Worker %5 = fmul x86_fp80 %4, 0xK4012F424000000000000 179*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fistpl $0", "{st},~{st}"(x86_fp80 %5) 180*9880d681SAndroid Build Coastguard Worker ret void 181*9880d681SAndroid Build Coastguard Worker} 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker; An input argument in a fixed position is implicitly popped by the asm only if 184*9880d681SAndroid Build Coastguard Worker; the input argument is tied to an output register, or it is in the clobber list. 185*9880d681SAndroid Build Coastguard Worker; The clobber list case is tested above. 186*9880d681SAndroid Build Coastguard Worker; 187*9880d681SAndroid Build Coastguard Worker; This doesn't implicitly pop the stack: 188*9880d681SAndroid Build Coastguard Worker; 189*9880d681SAndroid Build Coastguard Worker; void fist1(long double x, int *p) { 190*9880d681SAndroid Build Coastguard Worker; asm volatile ("fistl %1" : : "t"(x), "m"(*p)); 191*9880d681SAndroid Build Coastguard Worker; } 192*9880d681SAndroid Build Coastguard Worker; 193*9880d681SAndroid Build Coastguard Worker; CHECK: fist1 194*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 195*9880d681SAndroid Build Coastguard Worker; CHECK: fistl (%e 196*9880d681SAndroid Build Coastguard Worker; CHECK: fstp 197*9880d681SAndroid Build Coastguard Worker; CHECK: ret 198*9880d681SAndroid Build Coastguard Workerdefine void @fist1(x86_fp80 %x, i32* %p) nounwind ssp { 199*9880d681SAndroid Build Coastguard Workerentry: 200*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fistl $1", "{st},*m,~{memory},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %x, i32* %p) nounwind 201*9880d681SAndroid Build Coastguard Worker ret void 202*9880d681SAndroid Build Coastguard Worker} 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; Here, the input operand is tied to an output which means that is is 205*9880d681SAndroid Build Coastguard Worker; implicitly popped (and then the output is implicitly pushed). 206*9880d681SAndroid Build Coastguard Worker; 207*9880d681SAndroid Build Coastguard Worker; long double fist2(long double x, int *p) { 208*9880d681SAndroid Build Coastguard Worker; long double y; 209*9880d681SAndroid Build Coastguard Worker; asm ("fistl %1" : "=&t"(y) : "0"(x), "m"(*p) : "memory"); 210*9880d681SAndroid Build Coastguard Worker; return y; 211*9880d681SAndroid Build Coastguard Worker; } 212*9880d681SAndroid Build Coastguard Worker; 213*9880d681SAndroid Build Coastguard Worker; CHECK: fist2 214*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 215*9880d681SAndroid Build Coastguard Worker; CHECK: fistl (%e 216*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 217*9880d681SAndroid Build Coastguard Worker; CHECK: ret 218*9880d681SAndroid Build Coastguard Workerdefine x86_fp80 @fist2(x86_fp80 %x, i32* %p) nounwind ssp { 219*9880d681SAndroid Build Coastguard Workerentry: 220*9880d681SAndroid Build Coastguard Worker %0 = tail call x86_fp80 asm "fistl $2", "=&{st},0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %x, i32* %p) nounwind 221*9880d681SAndroid Build Coastguard Worker ret x86_fp80 %0 222*9880d681SAndroid Build Coastguard Worker} 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Worker; An 'f' constraint is never implicitly popped: 225*9880d681SAndroid Build Coastguard Worker; 226*9880d681SAndroid Build Coastguard Worker; void fucomp1(long double x, long double y) { 227*9880d681SAndroid Build Coastguard Worker; asm volatile ("fucomp %1" : : "t"(x), "f"(y) : "st"); 228*9880d681SAndroid Build Coastguard Worker; } 229*9880d681SAndroid Build Coastguard Worker; CHECK: fucomp1 230*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 231*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 232*9880d681SAndroid Build Coastguard Worker; CHECK: fucomp %st 233*9880d681SAndroid Build Coastguard Worker; CHECK: fstp 234*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 235*9880d681SAndroid Build Coastguard Worker; CHECK: ret 236*9880d681SAndroid Build Coastguard Workerdefine void @fucomp1(x86_fp80 %x, x86_fp80 %y) nounwind ssp { 237*9880d681SAndroid Build Coastguard Workerentry: 238*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fucomp $1", "{st},f,~{st},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %x, x86_fp80 %y) nounwind 239*9880d681SAndroid Build Coastguard Worker ret void 240*9880d681SAndroid Build Coastguard Worker} 241*9880d681SAndroid Build Coastguard Worker 242*9880d681SAndroid Build Coastguard Worker; The 'u' constraint is only popped implicitly when clobbered: 243*9880d681SAndroid Build Coastguard Worker; 244*9880d681SAndroid Build Coastguard Worker; void fucomp2(long double x, long double y) { 245*9880d681SAndroid Build Coastguard Worker; asm volatile ("fucomp %1" : : "t"(x), "u"(y) : "st"); 246*9880d681SAndroid Build Coastguard Worker; } 247*9880d681SAndroid Build Coastguard Worker; 248*9880d681SAndroid Build Coastguard Worker; void fucomp3(long double x, long double y) { 249*9880d681SAndroid Build Coastguard Worker; asm volatile ("fucompp %1" : : "t"(x), "u"(y) : "st", "st(1)"); 250*9880d681SAndroid Build Coastguard Worker; } 251*9880d681SAndroid Build Coastguard Worker; 252*9880d681SAndroid Build Coastguard Worker; CHECK: fucomp2 253*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 254*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 255*9880d681SAndroid Build Coastguard Worker; CHECK: fucomp %st(1) 256*9880d681SAndroid Build Coastguard Worker; CHECK: fstp 257*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 258*9880d681SAndroid Build Coastguard Worker; CHECK: ret 259*9880d681SAndroid Build Coastguard Worker; 260*9880d681SAndroid Build Coastguard Worker; CHECK: fucomp3 261*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 262*9880d681SAndroid Build Coastguard Worker; CHECK: fldt 263*9880d681SAndroid Build Coastguard Worker; CHECK: fucompp %st(1) 264*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 265*9880d681SAndroid Build Coastguard Worker; CHECK: ret 266*9880d681SAndroid Build Coastguard Workerdefine void @fucomp2(x86_fp80 %x, x86_fp80 %y) nounwind ssp { 267*9880d681SAndroid Build Coastguard Workerentry: 268*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fucomp $1", "{st},{st(1)},~{st},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %x, x86_fp80 %y) nounwind 269*9880d681SAndroid Build Coastguard Worker ret void 270*9880d681SAndroid Build Coastguard Worker} 271*9880d681SAndroid Build Coastguard Workerdefine void @fucomp3(x86_fp80 %x, x86_fp80 %y) nounwind ssp { 272*9880d681SAndroid Build Coastguard Workerentry: 273*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "fucompp $1", "{st},{st(1)},~{st},~{st(1)},~{dirflag},~{fpsr},~{flags}"(x86_fp80 %x, x86_fp80 %y) nounwind 274*9880d681SAndroid Build Coastguard Worker ret void 275*9880d681SAndroid Build Coastguard Worker} 276*9880d681SAndroid Build Coastguard Worker 277*9880d681SAndroid Build Coastguard Worker; One input, two outputs, one dead output. 278*9880d681SAndroid Build Coastguard Worker%complex = type { float, float } 279*9880d681SAndroid Build Coastguard Worker; CHECK: sincos1 280*9880d681SAndroid Build Coastguard Worker; CHECK: flds 281*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fxch 282*9880d681SAndroid Build Coastguard Worker; CHECK: sincos 283*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 284*9880d681SAndroid Build Coastguard Worker; CHECK: fstp %st(1) 285*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 286*9880d681SAndroid Build Coastguard Worker; CHECK: ret 287*9880d681SAndroid Build Coastguard Workerdefine float @sincos1(float %x) nounwind ssp { 288*9880d681SAndroid Build Coastguard Workerentry: 289*9880d681SAndroid Build Coastguard Worker %0 = tail call %complex asm "sincos", "={st},={st(1)},0,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind 290*9880d681SAndroid Build Coastguard Worker %asmresult = extractvalue %complex %0, 0 291*9880d681SAndroid Build Coastguard Worker ret float %asmresult 292*9880d681SAndroid Build Coastguard Worker} 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Worker; Same thing, swapped output operands. 295*9880d681SAndroid Build Coastguard Worker; CHECK: sincos2 296*9880d681SAndroid Build Coastguard Worker; CHECK: flds 297*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fxch 298*9880d681SAndroid Build Coastguard Worker; CHECK: sincos 299*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 300*9880d681SAndroid Build Coastguard Worker; CHECK: fstp %st(1) 301*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fstp 302*9880d681SAndroid Build Coastguard Worker; CHECK: ret 303*9880d681SAndroid Build Coastguard Workerdefine float @sincos2(float %x) nounwind ssp { 304*9880d681SAndroid Build Coastguard Workerentry: 305*9880d681SAndroid Build Coastguard Worker %0 = tail call %complex asm "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind 306*9880d681SAndroid Build Coastguard Worker %asmresult = extractvalue %complex %0, 1 307*9880d681SAndroid Build Coastguard Worker ret float %asmresult 308*9880d681SAndroid Build Coastguard Worker} 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Worker; Clobber st(0) after it was live-out/dead from the previous asm. 311*9880d681SAndroid Build Coastguard Worker; CHECK: sincos3 312*9880d681SAndroid Build Coastguard Worker; Load x, make a copy for the second asm. 313*9880d681SAndroid Build Coastguard Worker; CHECK: flds 314*9880d681SAndroid Build Coastguard Worker; CHECK: fld %st(0) 315*9880d681SAndroid Build Coastguard Worker; CHECK: sincos 316*9880d681SAndroid Build Coastguard Worker; Discard dead result in st(0), bring x to the top. 317*9880d681SAndroid Build Coastguard Worker; CHECK: fstp %st(0) 318*9880d681SAndroid Build Coastguard Worker; CHECK: fxch 319*9880d681SAndroid Build Coastguard Worker; x is now in st(0) for the second asm 320*9880d681SAndroid Build Coastguard Worker; CHECK: sincos 321*9880d681SAndroid Build Coastguard Worker; Discard both results. 322*9880d681SAndroid Build Coastguard Worker; CHECK: fstp 323*9880d681SAndroid Build Coastguard Worker; CHECK: fstp 324*9880d681SAndroid Build Coastguard Worker; CHECK: ret 325*9880d681SAndroid Build Coastguard Workerdefine float @sincos3(float %x) nounwind ssp { 326*9880d681SAndroid Build Coastguard Workerentry: 327*9880d681SAndroid Build Coastguard Worker %0 = tail call %complex asm sideeffect "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind 328*9880d681SAndroid Build Coastguard Worker %1 = tail call %complex asm sideeffect "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind 329*9880d681SAndroid Build Coastguard Worker %asmresult = extractvalue %complex %0, 0 330*9880d681SAndroid Build Coastguard Worker ret float %asmresult 331*9880d681SAndroid Build Coastguard Worker} 332*9880d681SAndroid Build Coastguard Worker 333*9880d681SAndroid Build Coastguard Worker; Pass the same value in two fixed stack slots. 334*9880d681SAndroid Build Coastguard Worker; CHECK: PR10602 335*9880d681SAndroid Build Coastguard Worker; CHECK: flds LCPI 336*9880d681SAndroid Build Coastguard Worker; CHECK: fld %st(0) 337*9880d681SAndroid Build Coastguard Worker; CHECK: fcomi %st(1), %st(0) 338*9880d681SAndroid Build Coastguard Workerdefine i32 @PR10602() nounwind ssp { 339*9880d681SAndroid Build Coastguard Workerentry: 340*9880d681SAndroid Build Coastguard Worker %0 = tail call i32 asm "fcomi $2, $1; pushf; pop $0", "=r,{st},{st(1)},~{dirflag},~{fpsr},~{flags}"(double 2.000000e+00, double 2.000000e+00) nounwind 341*9880d681SAndroid Build Coastguard Worker ret i32 %0 342*9880d681SAndroid Build Coastguard Worker} 343*9880d681SAndroid Build Coastguard Worker 344*9880d681SAndroid Build Coastguard Worker; <rdar://problem/16952634> 345*9880d681SAndroid Build Coastguard Worker; X87 stackifier asserted when there was an ST register defined by an 346*9880d681SAndroid Build Coastguard Worker; inline-asm instruction and the ST register was live across another 347*9880d681SAndroid Build Coastguard Worker; inline-asm instruction. 348*9880d681SAndroid Build Coastguard Worker; 349*9880d681SAndroid Build Coastguard Worker; INLINEASM <es:frndint> [sideeffect] [attdialect], $0:[regdef], %ST0<imp-def,tied5>, $1:[reguse tiedto:$0], %ST0<tied3>, $2:[clobber], %EFLAGS<earlyclobber,imp-def,dead> 350*9880d681SAndroid Build Coastguard Worker; INLINEASM <es:fldcw $0> [sideeffect] [mayload] [attdialect], $0:[mem], %EAX<undef>, 1, %noreg, 0, %noreg, $1:[clobber], %EFLAGS<earlyclobber,imp-def,dead> 351*9880d681SAndroid Build Coastguard Worker; %FP0<def> = COPY %ST0 352*9880d681SAndroid Build Coastguard Worker 353*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: _test_live_st 354*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm Start 355*9880d681SAndroid Build Coastguard Worker; CHECK: frndint 356*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm End 357*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm Start 358*9880d681SAndroid Build Coastguard Worker; CHECK: fldcw 359*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm End 360*9880d681SAndroid Build Coastguard Worker 361*9880d681SAndroid Build Coastguard Worker%struct.fpu_t = type { [8 x x86_fp80], x86_fp80, %struct.anon1, %struct.anon2, i32, i8, [15 x i8] } 362*9880d681SAndroid Build Coastguard Worker%struct.anon1 = type { i32, i32, i32 } 363*9880d681SAndroid Build Coastguard Worker%struct.anon2 = type { i32, i32, i32, i32 } 364*9880d681SAndroid Build Coastguard Worker 365*9880d681SAndroid Build Coastguard Worker@fpu = external global %struct.fpu_t, align 16 366*9880d681SAndroid Build Coastguard Worker 367*9880d681SAndroid Build Coastguard Worker; Function Attrs: ssp 368*9880d681SAndroid Build Coastguard Workerdefine void @test_live_st(i32 %a1) { 369*9880d681SAndroid Build Coastguard Workerentry: 370*9880d681SAndroid Build Coastguard Worker %0 = load x86_fp80, x86_fp80* undef, align 16 371*9880d681SAndroid Build Coastguard Worker %cond = icmp eq i32 %a1, 1 372*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %sw.bb4.i, label %_Z5tointRKe.exit 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Workersw.bb4.i: 375*9880d681SAndroid Build Coastguard Worker %1 = call x86_fp80 asm sideeffect "frndint", "={st},0,~{dirflag},~{fpsr},~{flags}"(x86_fp80 %0) 376*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"(i32* undef) 377*9880d681SAndroid Build Coastguard Worker br label %_Z5tointRKe.exit 378*9880d681SAndroid Build Coastguard Worker 379*9880d681SAndroid Build Coastguard Worker_Z5tointRKe.exit: 380*9880d681SAndroid Build Coastguard Worker %result.0.i = phi x86_fp80 [ %1, %sw.bb4.i ], [ %0, %entry ] 381*9880d681SAndroid Build Coastguard Worker %conv.i1814 = fptosi x86_fp80 %result.0.i to i32 382*9880d681SAndroid Build Coastguard Worker %conv626 = sitofp i32 %conv.i1814 to x86_fp80 383*9880d681SAndroid Build Coastguard Worker store x86_fp80 %conv626, x86_fp80* getelementptr inbounds (%struct.fpu_t, %struct.fpu_t* @fpu, i32 0, i32 1) 384*9880d681SAndroid Build Coastguard Worker br label %return 385*9880d681SAndroid Build Coastguard Worker 386*9880d681SAndroid Build Coastguard Workerreturn: 387*9880d681SAndroid Build Coastguard Worker ret void 388*9880d681SAndroid Build Coastguard Worker} 389*9880d681SAndroid Build Coastguard Worker 390*9880d681SAndroid Build Coastguard Worker; Check that x87 stackifier is correctly rewriting FP registers to ST registers. 391*9880d681SAndroid Build Coastguard Worker; 392*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: _test_operand_rewrite 393*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm Start 394*9880d681SAndroid Build Coastguard Worker; CHECK: foo %st(0), %st(1) 395*9880d681SAndroid Build Coastguard Worker; CHECK: ## InlineAsm End 396*9880d681SAndroid Build Coastguard Worker 397*9880d681SAndroid Build Coastguard Workerdefine double @test_operand_rewrite() { 398*9880d681SAndroid Build Coastguard Workerentry: 399*9880d681SAndroid Build Coastguard Worker %0 = tail call { double, double } asm sideeffect "foo $0, $1", "={st},={st(1)},~{dirflag},~{fpsr},~{flags}"() 400*9880d681SAndroid Build Coastguard Worker %asmresult = extractvalue { double, double } %0, 0 401*9880d681SAndroid Build Coastguard Worker %asmresult1 = extractvalue { double, double } %0, 1 402*9880d681SAndroid Build Coastguard Worker %sub = fsub double %asmresult, %asmresult1 403*9880d681SAndroid Build Coastguard Worker ret double %sub 404*9880d681SAndroid Build Coastguard Worker} 405