1 ; Test negative integer absolute. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 ; Test i32->i32 negative absolute using slt. 6 define i32 @f1(i32 %val) { 7 ; CHECK-LABEL: f1: 8 ; CHECK: lnr %r2, %r2 9 ; CHECK: br %r14 10 %cmp = icmp slt i32 %val, 0 11 %neg = sub i32 0, %val 12 %abs = select i1 %cmp, i32 %neg, i32 %val 13 %res = sub i32 0, %abs 14 ret i32 %res 15 } 16 17 ; Test i32->i32 negative absolute using sle. 18 define i32 @f2(i32 %val) { 19 ; CHECK-LABEL: f2: 20 ; CHECK: lnr %r2, %r2 21 ; CHECK: br %r14 22 %cmp = icmp sle i32 %val, 0 23 %neg = sub i32 0, %val 24 %abs = select i1 %cmp, i32 %neg, i32 %val 25 %res = sub i32 0, %abs 26 ret i32 %res 27 } 28 29 ; Test i32->i32 negative absolute using sgt. 30 define i32 @f3(i32 %val) { 31 ; CHECK-LABEL: f3: 32 ; CHECK: lnr %r2, %r2 33 ; CHECK: br %r14 34 %cmp = icmp sgt i32 %val, 0 35 %neg = sub i32 0, %val 36 %abs = select i1 %cmp, i32 %val, i32 %neg 37 %res = sub i32 0, %abs 38 ret i32 %res 39 } 40 41 ; Test i32->i32 negative absolute using sge. 42 define i32 @f4(i32 %val) { 43 ; CHECK-LABEL: f4: 44 ; CHECK: lnr %r2, %r2 45 ; CHECK: br %r14 46 %cmp = icmp sge i32 %val, 0 47 %neg = sub i32 0, %val 48 %abs = select i1 %cmp, i32 %val, i32 %neg 49 %res = sub i32 0, %abs 50 ret i32 %res 51 } 52 53 ; Test i32->i64 negative absolute. 54 define i64 @f5(i32 %val) { 55 ; CHECK-LABEL: f5: 56 ; CHECK: lngfr %r2, %r2 57 ; CHECK: br %r14 58 %ext = sext i32 %val to i64 59 %cmp = icmp slt i64 %ext, 0 60 %neg = sub i64 0, %ext 61 %abs = select i1 %cmp, i64 %neg, i64 %ext 62 %res = sub i64 0, %abs 63 ret i64 %res 64 } 65 66 ; Test i32->i64 negative absolute that uses an "in-register" form of 67 ; sign extension. 68 define i64 @f6(i64 %val) { 69 ; CHECK-LABEL: f6: 70 ; CHECK: lngfr %r2, %r2 71 ; CHECK: br %r14 72 %trunc = trunc i64 %val to i32 73 %ext = sext i32 %trunc to i64 74 %cmp = icmp slt i64 %ext, 0 75 %neg = sub i64 0, %ext 76 %abs = select i1 %cmp, i64 %neg, i64 %ext 77 %res = sub i64 0, %abs 78 ret i64 %res 79 } 80 81 ; Test i64 negative absolute. 82 define i64 @f7(i64 %val) { 83 ; CHECK-LABEL: f7: 84 ; CHECK: lngr %r2, %r2 85 ; CHECK: br %r14 86 %cmp = icmp slt i64 %val, 0 87 %neg = sub i64 0, %val 88 %abs = select i1 %cmp, i64 %neg, i64 %val 89 %res = sub i64 0, %abs 90 ret i64 %res 91 } 92 93 ; Test another form of f6, which is that produced by InstCombine. 94 define i64 @f8(i64 %val) { 95 ; CHECK-LABEL: f8: 96 ; CHECK: lngfr %r2, %r2 97 ; CHECK: br %r14 98 %shl = shl i64 %val, 32 99 %ashr = ashr i64 %shl, 32 100 %neg = sub i64 0, %ashr 101 %cmp = icmp slt i64 %shl, 0 102 %abs = select i1 %cmp, i64 %neg, i64 %ashr 103 %res = sub i64 0, %abs 104 ret i64 %res 105 } 106 107 ; Try again with sle rather than slt. 108 define i64 @f9(i64 %val) { 109 ; CHECK-LABEL: f9: 110 ; CHECK: lngfr %r2, %r2 111 ; CHECK: br %r14 112 %shl = shl i64 %val, 32 113 %ashr = ashr i64 %shl, 32 114 %neg = sub i64 0, %ashr 115 %cmp = icmp sle i64 %shl, 0 116 %abs = select i1 %cmp, i64 %neg, i64 %ashr 117 %res = sub i64 0, %abs 118 ret i64 %res 119 } 120 121 ; Repeat f8 with the operands reversed. 122 define i64 @f10(i64 %val) { 123 ; CHECK-LABEL: f10: 124 ; CHECK: lngfr %r2, %r2 125 ; CHECK: br %r14 126 %shl = shl i64 %val, 32 127 %ashr = ashr i64 %shl, 32 128 %neg = sub i64 0, %ashr 129 %cmp = icmp sgt i64 %shl, 0 130 %abs = select i1 %cmp, i64 %ashr, i64 %neg 131 %res = sub i64 0, %abs 132 ret i64 %res 133 } 134 135 ; Try again with sge rather than sgt. 136 define i64 @f11(i64 %val) { 137 ; CHECK-LABEL: f11: 138 ; CHECK: lngfr %r2, %r2 139 ; CHECK: br %r14 140 %shl = shl i64 %val, 32 141 %ashr = ashr i64 %shl, 32 142 %neg = sub i64 0, %ashr 143 %cmp = icmp sge i64 %shl, 0 144 %abs = select i1 %cmp, i64 %ashr, i64 %neg 145 %res = sub i64 0, %abs 146 ret i64 %res 147 } 148 149 ; Repeat f8 with the negation coming from swapped operands. 150 define i64 @f12(i64 %val) { 151 ; CHECK-LABEL: f12: 152 ; CHECK: lngfr %r2, %r2 153 ; CHECK: br %r14 154 %shl = shl i64 %val, 32 155 %ashr = ashr i64 %shl, 32 156 %neg = sub i64 0, %ashr 157 %cmp = icmp slt i64 %shl, 0 158 %negabs = select i1 %cmp, i64 %ashr, i64 %neg 159 ret i64 %negabs 160 } 161 162 ; Likewise f9. 163 define i64 @f13(i64 %val) { 164 ; CHECK-LABEL: f13: 165 ; CHECK: lngfr %r2, %r2 166 ; CHECK: br %r14 167 %shl = shl i64 %val, 32 168 %ashr = ashr i64 %shl, 32 169 %neg = sub i64 0, %ashr 170 %cmp = icmp sle i64 %shl, 0 171 %negabs = select i1 %cmp, i64 %ashr, i64 %neg 172 ret i64 %negabs 173 } 174 175 ; Likewise f10. 176 define i64 @f14(i64 %val) { 177 ; CHECK-LABEL: f14: 178 ; CHECK: lngfr %r2, %r2 179 ; CHECK: br %r14 180 %shl = shl i64 %val, 32 181 %ashr = ashr i64 %shl, 32 182 %neg = sub i64 0, %ashr 183 %cmp = icmp sgt i64 %shl, 0 184 %negabs = select i1 %cmp, i64 %neg, i64 %ashr 185 ret i64 %negabs 186 } 187 188 ; Likewise f11. 189 define i64 @f15(i64 %val) { 190 ; CHECK-LABEL: f15: 191 ; CHECK: lngfr %r2, %r2 192 ; CHECK: br %r14 193 %shl = shl i64 %val, 32 194 %ashr = ashr i64 %shl, 32 195 %neg = sub i64 0, %ashr 196 %cmp = icmp sge i64 %shl, 0 197 %negabs = select i1 %cmp, i64 %neg, i64 %ashr 198 ret i64 %negabs 199 } 200 201 ; Repeat f5 with the comparison on the unextended value. 202 define i64 @f16(i32 %val) { 203 ; CHECK-LABEL: f16: 204 ; CHECK: lngfr %r2, %r2 205 ; CHECK: br %r14 206 %ext = sext i32 %val to i64 207 %cmp = icmp slt i32 %val, 0 208 %neg = sub i64 0, %ext 209 %abs = select i1 %cmp, i64 %neg, i64 %ext 210 %res = sub i64 0, %abs 211 ret i64 %res 212 } 213 214 ; And again with the negation coming from swapped operands. 215 define i64 @f17(i32 %val) { 216 ; CHECK-LABEL: f17: 217 ; CHECK: lngfr %r2, %r2 218 ; CHECK: br %r14 219 %ext = sext i32 %val to i64 220 %cmp = icmp slt i32 %val, 0 221 %neg = sub i64 0, %ext 222 %abs = select i1 %cmp, i64 %ext, i64 %neg 223 ret i64 %abs 224 } 225