1 ; Test copysign operations. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 declare float @copysignf(float, float) readnone 6 declare double @copysign(double, double) readnone 7 ; FIXME: not really the correct prototype for SystemZ. 8 declare fp128 @copysignl(fp128, fp128) readnone 9 10 ; Test f32 copies in which the sign comes from an f32. 11 define 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. 21 define 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. 32 define 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. 45 define 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. 56 define 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. 66 define 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. 81 define 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. 97 define 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. 114 define 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