1; Test copysign operations. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5declare float @copysignf(float, float) readnone 6declare double @copysign(double, double) readnone 7; FIXME: not really the correct prototype for SystemZ. 8declare fp128 @copysignl(fp128, fp128) readnone 9 10; Test f32 copies in which the sign comes from an f32. 11define float @f1(float %a, float %b) { 12; CHECK-LABEL: f1: 13; CHECK-NOT: %f2 14; CHECK: cpsdr %f0, %f0, %f2 15; CHECK: br %r14 16 %res = call float @copysignf(float %a, float %b) readnone 17 ret float %res 18} 19 20; Test f32 copies in which the sign comes from an f64. 21define float @f2(float %a, double %bd) { 22; CHECK-LABEL: f2: 23; CHECK-NOT: %f2 24; CHECK: cpsdr %f0, %f0, %f2 25; CHECK: br %r14 26 %b = fptrunc double %bd to float 27 %res = call float @copysignf(float %a, float %b) readnone 28 ret float %res 29} 30 31; Test f32 copies in which the sign comes from an f128. 32define float @f3(float %a, fp128 *%bptr) { 33; CHECK-LABEL: f3: 34; CHECK: ld [[BHIGH:%f[0-7]]], 0(%r2) 35; CHECK: ld [[BLOW:%f[0-7]]], 8(%r2) 36; CHECK: cpsdr %f0, %f0, [[BHIGH]] 37; CHECK: br %r14 38 %bl = load volatile fp128 , fp128 *%bptr 39 %b = fptrunc fp128 %bl to float 40 %res = call float @copysignf(float %a, float %b) readnone 41 ret float %res 42} 43 44; Test f64 copies in which the sign comes from an f32. 45define double @f4(double %a, float %bf) { 46; CHECK-LABEL: f4: 47; CHECK-NOT: %f2 48; CHECK: cpsdr %f0, %f0, %f2 49; CHECK: br %r14 50 %b = fpext float %bf to double 51 %res = call double @copysign(double %a, double %b) readnone 52 ret double %res 53} 54 55; Test f64 copies in which the sign comes from an f64. 56define double @f5(double %a, double %b) { 57; CHECK-LABEL: f5: 58; CHECK-NOT: %f2 59; CHECK: cpsdr %f0, %f0, %f2 60; CHECK: br %r14 61 %res = call double @copysign(double %a, double %b) readnone 62 ret double %res 63} 64 65; Test f64 copies in which the sign comes from an f128. 66define double @f6(double %a, fp128 *%bptr) { 67; CHECK-LABEL: f6: 68; CHECK: ld [[BHIGH:%f[0-7]]], 0(%r2) 69; CHECK: ld [[BLOW:%f[0-7]]], 8(%r2) 70; CHECK: cpsdr %f0, %f0, [[BHIGH]] 71; CHECK: br %r14 72 %bl = load volatile fp128 , fp128 *%bptr 73 %b = fptrunc fp128 %bl to double 74 %res = call double @copysign(double %a, double %b) readnone 75 ret double %res 76} 77 78; Test f128 copies in which the sign comes from an f32. We shouldn't 79; need any register shuffling here; %a should be tied to %c, with CPSDR 80; just changing the high register. 81define void @f7(fp128 *%cptr, fp128 *%aptr, float %bf) { 82; CHECK-LABEL: f7: 83; CHECK: ld [[AHIGH:%f[0-7]]], 0(%r3) 84; CHECK: ld [[ALOW:%f[0-7]]], 8(%r3) 85; CHECK: cpsdr [[AHIGH]], [[AHIGH]], %f0 86; CHECK: std [[AHIGH]], 0(%r2) 87; CHECK: std [[ALOW]], 8(%r2) 88; CHECK: br %r14 89 %a = load volatile fp128 , fp128 *%aptr 90 %b = fpext float %bf to fp128 91 %c = call fp128 @copysignl(fp128 %a, fp128 %b) readnone 92 store fp128 %c, fp128 *%cptr 93 ret void 94} 95 96; As above, but the sign comes from an f64. 97define void @f8(fp128 *%cptr, fp128 *%aptr, double %bd) { 98; CHECK-LABEL: f8: 99; CHECK: ld [[AHIGH:%f[0-7]]], 0(%r3) 100; CHECK: ld [[ALOW:%f[0-7]]], 8(%r3) 101; CHECK: cpsdr [[AHIGH]], [[AHIGH]], %f0 102; CHECK: std [[AHIGH]], 0(%r2) 103; CHECK: std [[ALOW]], 8(%r2) 104; CHECK: br %r14 105 %a = load volatile fp128 , fp128 *%aptr 106 %b = fpext double %bd to fp128 107 %c = call fp128 @copysignl(fp128 %a, fp128 %b) readnone 108 store fp128 %c, fp128 *%cptr 109 ret void 110} 111 112; As above, but the sign comes from an f128. Don't require the low part 113; of %b to be loaded, since it isn't used. 114define void @f9(fp128 *%cptr, fp128 *%aptr, fp128 *%bptr) { 115; CHECK-LABEL: f9: 116; CHECK: ld [[AHIGH:%f[0-7]]], 0(%r3) 117; CHECK: ld [[ALOW:%f[0-7]]], 8(%r3) 118; CHECK: ld [[BHIGH:%f[0-7]]], 0(%r4) 119; CHECK: cpsdr [[AHIGH]], [[AHIGH]], [[BHIGH]] 120; CHECK: std [[AHIGH]], 0(%r2) 121; CHECK: std [[ALOW]], 8(%r2) 122; CHECK: br %r14 123 %a = load volatile fp128 , fp128 *%aptr 124 %b = load volatile fp128 , fp128 *%bptr 125 %c = call fp128 @copysignl(fp128 %a, fp128 %b) readnone 126 store fp128 %c, fp128 *%cptr 127 ret void 128} 129