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. 6define 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. 18define 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. 30define 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. 42define 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. 54define 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. 68define 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. 82define 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. 94define 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. 108define 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. 122define 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. 136define 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. 150define 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. 163define 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. 176define 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. 189define 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. 202define 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. 215define 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