1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s 3 4; These test cases are inspired by C++2a std::midpoint(). 5; See https://bugs.llvm.org/show_bug.cgi?id=40965 6 7; ---------------------------------------------------------------------------- ; 8; 32-bit width 9; ---------------------------------------------------------------------------- ; 10 11; Values come from regs 12 13define i32 @scalar_i32_signed_reg_reg(i32 %a1, i32 %a2) nounwind { 14; CHECK-LABEL: scalar_i32_signed_reg_reg: 15; CHECK: // %bb.0: 16; CHECK-NEXT: cmp w0, w1 17; CHECK-NEXT: csel w9, w1, w0, gt 18; CHECK-NEXT: csel w10, w0, w1, gt 19; CHECK-NEXT: mov w8, #-1 20; CHECK-NEXT: sub w9, w10, w9 21; CHECK-NEXT: cneg w8, w8, le 22; CHECK-NEXT: lsr w9, w9, #1 23; CHECK-NEXT: madd w0, w9, w8, w0 24; CHECK-NEXT: ret 25 %t3 = icmp sgt i32 %a1, %a2 ; signed 26 %t4 = select i1 %t3, i32 -1, i32 1 27 %t5 = select i1 %t3, i32 %a2, i32 %a1 28 %t6 = select i1 %t3, i32 %a1, i32 %a2 29 %t7 = sub i32 %t6, %t5 30 %t8 = lshr i32 %t7, 1 31 %t9 = mul nsw i32 %t8, %t4 ; signed 32 %a10 = add nsw i32 %t9, %a1 ; signed 33 ret i32 %a10 34} 35 36define i32 @scalar_i32_unsigned_reg_reg(i32 %a1, i32 %a2) nounwind { 37; CHECK-LABEL: scalar_i32_unsigned_reg_reg: 38; CHECK: // %bb.0: 39; CHECK-NEXT: cmp w0, w1 40; CHECK-NEXT: csel w9, w1, w0, hi 41; CHECK-NEXT: csel w10, w0, w1, hi 42; CHECK-NEXT: mov w8, #-1 43; CHECK-NEXT: sub w9, w10, w9 44; CHECK-NEXT: cneg w8, w8, ls 45; CHECK-NEXT: lsr w9, w9, #1 46; CHECK-NEXT: madd w0, w9, w8, w0 47; CHECK-NEXT: ret 48 %t3 = icmp ugt i32 %a1, %a2 49 %t4 = select i1 %t3, i32 -1, i32 1 50 %t5 = select i1 %t3, i32 %a2, i32 %a1 51 %t6 = select i1 %t3, i32 %a1, i32 %a2 52 %t7 = sub i32 %t6, %t5 53 %t8 = lshr i32 %t7, 1 54 %t9 = mul i32 %t8, %t4 55 %a10 = add i32 %t9, %a1 56 ret i32 %a10 57} 58 59; Values are loaded. Only check signed case. 60 61define i32 @scalar_i32_signed_mem_reg(i32* %a1_addr, i32 %a2) nounwind { 62; CHECK-LABEL: scalar_i32_signed_mem_reg: 63; CHECK: // %bb.0: 64; CHECK-NEXT: ldr w8, [x0] 65; CHECK-NEXT: mov w9, #-1 66; CHECK-NEXT: cmp w8, w1 67; CHECK-NEXT: csel w10, w1, w8, gt 68; CHECK-NEXT: csel w11, w8, w1, gt 69; CHECK-NEXT: sub w10, w11, w10 70; CHECK-NEXT: cneg w9, w9, le 71; CHECK-NEXT: lsr w10, w10, #1 72; CHECK-NEXT: madd w0, w10, w9, w8 73; CHECK-NEXT: ret 74 %a1 = load i32, i32* %a1_addr 75 %t3 = icmp sgt i32 %a1, %a2 ; signed 76 %t4 = select i1 %t3, i32 -1, i32 1 77 %t5 = select i1 %t3, i32 %a2, i32 %a1 78 %t6 = select i1 %t3, i32 %a1, i32 %a2 79 %t7 = sub i32 %t6, %t5 80 %t8 = lshr i32 %t7, 1 81 %t9 = mul nsw i32 %t8, %t4 ; signed 82 %a10 = add nsw i32 %t9, %a1 ; signed 83 ret i32 %a10 84} 85 86define i32 @scalar_i32_signed_reg_mem(i32 %a1, i32* %a2_addr) nounwind { 87; CHECK-LABEL: scalar_i32_signed_reg_mem: 88; CHECK: // %bb.0: 89; CHECK-NEXT: ldr w8, [x1] 90; CHECK-NEXT: mov w9, #-1 91; CHECK-NEXT: cmp w0, w8 92; CHECK-NEXT: csel w10, w8, w0, gt 93; CHECK-NEXT: csel w8, w0, w8, gt 94; CHECK-NEXT: sub w8, w8, w10 95; CHECK-NEXT: cneg w9, w9, le 96; CHECK-NEXT: lsr w8, w8, #1 97; CHECK-NEXT: madd w0, w8, w9, w0 98; CHECK-NEXT: ret 99 %a2 = load i32, i32* %a2_addr 100 %t3 = icmp sgt i32 %a1, %a2 ; signed 101 %t4 = select i1 %t3, i32 -1, i32 1 102 %t5 = select i1 %t3, i32 %a2, i32 %a1 103 %t6 = select i1 %t3, i32 %a1, i32 %a2 104 %t7 = sub i32 %t6, %t5 105 %t8 = lshr i32 %t7, 1 106 %t9 = mul nsw i32 %t8, %t4 ; signed 107 %a10 = add nsw i32 %t9, %a1 ; signed 108 ret i32 %a10 109} 110 111define i32 @scalar_i32_signed_mem_mem(i32* %a1_addr, i32* %a2_addr) nounwind { 112; CHECK-LABEL: scalar_i32_signed_mem_mem: 113; CHECK: // %bb.0: 114; CHECK-NEXT: ldr w8, [x0] 115; CHECK-NEXT: ldr w9, [x1] 116; CHECK-NEXT: mov w10, #-1 117; CHECK-NEXT: cmp w8, w9 118; CHECK-NEXT: csel w11, w9, w8, gt 119; CHECK-NEXT: csel w9, w8, w9, gt 120; CHECK-NEXT: sub w9, w9, w11 121; CHECK-NEXT: cneg w10, w10, le 122; CHECK-NEXT: lsr w9, w9, #1 123; CHECK-NEXT: madd w0, w9, w10, w8 124; CHECK-NEXT: ret 125 %a1 = load i32, i32* %a1_addr 126 %a2 = load i32, i32* %a2_addr 127 %t3 = icmp sgt i32 %a1, %a2 ; signed 128 %t4 = select i1 %t3, i32 -1, i32 1 129 %t5 = select i1 %t3, i32 %a2, i32 %a1 130 %t6 = select i1 %t3, i32 %a1, i32 %a2 131 %t7 = sub i32 %t6, %t5 132 %t8 = lshr i32 %t7, 1 133 %t9 = mul nsw i32 %t8, %t4 ; signed 134 %a10 = add nsw i32 %t9, %a1 ; signed 135 ret i32 %a10 136} 137 138; ---------------------------------------------------------------------------- ; 139; 64-bit width 140; ---------------------------------------------------------------------------- ; 141 142; Values come from regs 143 144define i64 @scalar_i64_signed_reg_reg(i64 %a1, i64 %a2) nounwind { 145; CHECK-LABEL: scalar_i64_signed_reg_reg: 146; CHECK: // %bb.0: 147; CHECK-NEXT: cmp x0, x1 148; CHECK-NEXT: csel x9, x1, x0, gt 149; CHECK-NEXT: csel x10, x0, x1, gt 150; CHECK-NEXT: mov x8, #-1 151; CHECK-NEXT: sub x9, x10, x9 152; CHECK-NEXT: cneg x8, x8, le 153; CHECK-NEXT: lsr x9, x9, #1 154; CHECK-NEXT: madd x0, x9, x8, x0 155; CHECK-NEXT: ret 156 %t3 = icmp sgt i64 %a1, %a2 ; signed 157 %t4 = select i1 %t3, i64 -1, i64 1 158 %t5 = select i1 %t3, i64 %a2, i64 %a1 159 %t6 = select i1 %t3, i64 %a1, i64 %a2 160 %t7 = sub i64 %t6, %t5 161 %t8 = lshr i64 %t7, 1 162 %t9 = mul nsw i64 %t8, %t4 ; signed 163 %a10 = add nsw i64 %t9, %a1 ; signed 164 ret i64 %a10 165} 166 167define i64 @scalar_i64_unsigned_reg_reg(i64 %a1, i64 %a2) nounwind { 168; CHECK-LABEL: scalar_i64_unsigned_reg_reg: 169; CHECK: // %bb.0: 170; CHECK-NEXT: cmp x0, x1 171; CHECK-NEXT: csel x9, x1, x0, hi 172; CHECK-NEXT: csel x10, x0, x1, hi 173; CHECK-NEXT: mov x8, #-1 174; CHECK-NEXT: sub x9, x10, x9 175; CHECK-NEXT: cneg x8, x8, ls 176; CHECK-NEXT: lsr x9, x9, #1 177; CHECK-NEXT: madd x0, x9, x8, x0 178; CHECK-NEXT: ret 179 %t3 = icmp ugt i64 %a1, %a2 180 %t4 = select i1 %t3, i64 -1, i64 1 181 %t5 = select i1 %t3, i64 %a2, i64 %a1 182 %t6 = select i1 %t3, i64 %a1, i64 %a2 183 %t7 = sub i64 %t6, %t5 184 %t8 = lshr i64 %t7, 1 185 %t9 = mul i64 %t8, %t4 186 %a10 = add i64 %t9, %a1 187 ret i64 %a10 188} 189 190; Values are loaded. Only check signed case. 191 192define i64 @scalar_i64_signed_mem_reg(i64* %a1_addr, i64 %a2) nounwind { 193; CHECK-LABEL: scalar_i64_signed_mem_reg: 194; CHECK: // %bb.0: 195; CHECK-NEXT: ldr x8, [x0] 196; CHECK-NEXT: mov x9, #-1 197; CHECK-NEXT: cmp x8, x1 198; CHECK-NEXT: csel x10, x1, x8, gt 199; CHECK-NEXT: csel x11, x8, x1, gt 200; CHECK-NEXT: sub x10, x11, x10 201; CHECK-NEXT: cneg x9, x9, le 202; CHECK-NEXT: lsr x10, x10, #1 203; CHECK-NEXT: madd x0, x10, x9, x8 204; CHECK-NEXT: ret 205 %a1 = load i64, i64* %a1_addr 206 %t3 = icmp sgt i64 %a1, %a2 ; signed 207 %t4 = select i1 %t3, i64 -1, i64 1 208 %t5 = select i1 %t3, i64 %a2, i64 %a1 209 %t6 = select i1 %t3, i64 %a1, i64 %a2 210 %t7 = sub i64 %t6, %t5 211 %t8 = lshr i64 %t7, 1 212 %t9 = mul nsw i64 %t8, %t4 ; signed 213 %a10 = add nsw i64 %t9, %a1 ; signed 214 ret i64 %a10 215} 216 217define i64 @scalar_i64_signed_reg_mem(i64 %a1, i64* %a2_addr) nounwind { 218; CHECK-LABEL: scalar_i64_signed_reg_mem: 219; CHECK: // %bb.0: 220; CHECK-NEXT: ldr x8, [x1] 221; CHECK-NEXT: mov x9, #-1 222; CHECK-NEXT: cmp x0, x8 223; CHECK-NEXT: csel x10, x8, x0, gt 224; CHECK-NEXT: csel x8, x0, x8, gt 225; CHECK-NEXT: sub x8, x8, x10 226; CHECK-NEXT: cneg x9, x9, le 227; CHECK-NEXT: lsr x8, x8, #1 228; CHECK-NEXT: madd x0, x8, x9, x0 229; CHECK-NEXT: ret 230 %a2 = load i64, i64* %a2_addr 231 %t3 = icmp sgt i64 %a1, %a2 ; signed 232 %t4 = select i1 %t3, i64 -1, i64 1 233 %t5 = select i1 %t3, i64 %a2, i64 %a1 234 %t6 = select i1 %t3, i64 %a1, i64 %a2 235 %t7 = sub i64 %t6, %t5 236 %t8 = lshr i64 %t7, 1 237 %t9 = mul nsw i64 %t8, %t4 ; signed 238 %a10 = add nsw i64 %t9, %a1 ; signed 239 ret i64 %a10 240} 241 242define i64 @scalar_i64_signed_mem_mem(i64* %a1_addr, i64* %a2_addr) nounwind { 243; CHECK-LABEL: scalar_i64_signed_mem_mem: 244; CHECK: // %bb.0: 245; CHECK-NEXT: ldr x8, [x0] 246; CHECK-NEXT: ldr x9, [x1] 247; CHECK-NEXT: mov x10, #-1 248; CHECK-NEXT: cmp x8, x9 249; CHECK-NEXT: csel x11, x9, x8, gt 250; CHECK-NEXT: csel x9, x8, x9, gt 251; CHECK-NEXT: sub x9, x9, x11 252; CHECK-NEXT: cneg x10, x10, le 253; CHECK-NEXT: lsr x9, x9, #1 254; CHECK-NEXT: madd x0, x9, x10, x8 255; CHECK-NEXT: ret 256 %a1 = load i64, i64* %a1_addr 257 %a2 = load i64, i64* %a2_addr 258 %t3 = icmp sgt i64 %a1, %a2 ; signed 259 %t4 = select i1 %t3, i64 -1, i64 1 260 %t5 = select i1 %t3, i64 %a2, i64 %a1 261 %t6 = select i1 %t3, i64 %a1, i64 %a2 262 %t7 = sub i64 %t6, %t5 263 %t8 = lshr i64 %t7, 1 264 %t9 = mul nsw i64 %t8, %t4 ; signed 265 %a10 = add nsw i64 %t9, %a1 ; signed 266 ret i64 %a10 267} 268 269; ---------------------------------------------------------------------------- ; 270; 16-bit width 271; ---------------------------------------------------------------------------- ; 272 273; Values come from regs 274 275define i16 @scalar_i16_signed_reg_reg(i16 %a1, i16 %a2) nounwind { 276; CHECK-LABEL: scalar_i16_signed_reg_reg: 277; CHECK: // %bb.0: 278; CHECK-NEXT: sxth w8, w0 279; CHECK-NEXT: mov w9, #-1 280; CHECK-NEXT: cmp w8, w1, sxth 281; CHECK-NEXT: cneg w8, w9, le 282; CHECK-NEXT: csel w9, w1, w0, gt 283; CHECK-NEXT: csel w10, w0, w1, gt 284; CHECK-NEXT: sub w9, w10, w9 285; CHECK-NEXT: ubfx w9, w9, #1, #15 286; CHECK-NEXT: madd w0, w9, w8, w0 287; CHECK-NEXT: ret 288 %t3 = icmp sgt i16 %a1, %a2 ; signed 289 %t4 = select i1 %t3, i16 -1, i16 1 290 %t5 = select i1 %t3, i16 %a2, i16 %a1 291 %t6 = select i1 %t3, i16 %a1, i16 %a2 292 %t7 = sub i16 %t6, %t5 293 %t8 = lshr i16 %t7, 1 294 %t9 = mul nsw i16 %t8, %t4 ; signed 295 %a10 = add nsw i16 %t9, %a1 ; signed 296 ret i16 %a10 297} 298 299define i16 @scalar_i16_unsigned_reg_reg(i16 %a1, i16 %a2) nounwind { 300; CHECK-LABEL: scalar_i16_unsigned_reg_reg: 301; CHECK: // %bb.0: 302; CHECK-NEXT: and w8, w0, #0xffff 303; CHECK-NEXT: mov w9, #-1 304; CHECK-NEXT: cmp w8, w1, uxth 305; CHECK-NEXT: cneg w8, w9, ls 306; CHECK-NEXT: csel w9, w1, w0, hi 307; CHECK-NEXT: csel w10, w0, w1, hi 308; CHECK-NEXT: sub w9, w10, w9 309; CHECK-NEXT: ubfx w9, w9, #1, #15 310; CHECK-NEXT: madd w0, w9, w8, w0 311; CHECK-NEXT: ret 312 %t3 = icmp ugt i16 %a1, %a2 313 %t4 = select i1 %t3, i16 -1, i16 1 314 %t5 = select i1 %t3, i16 %a2, i16 %a1 315 %t6 = select i1 %t3, i16 %a1, i16 %a2 316 %t7 = sub i16 %t6, %t5 317 %t8 = lshr i16 %t7, 1 318 %t9 = mul i16 %t8, %t4 319 %a10 = add i16 %t9, %a1 320 ret i16 %a10 321} 322 323; Values are loaded. Only check signed case. 324 325define i16 @scalar_i16_signed_mem_reg(i16* %a1_addr, i16 %a2) nounwind { 326; CHECK-LABEL: scalar_i16_signed_mem_reg: 327; CHECK: // %bb.0: 328; CHECK-NEXT: ldrsh w8, [x0] 329; CHECK-NEXT: mov w9, #-1 330; CHECK-NEXT: cmp w8, w1, sxth 331; CHECK-NEXT: csel w10, w1, w8, gt 332; CHECK-NEXT: csel w11, w8, w1, gt 333; CHECK-NEXT: sub w10, w11, w10 334; CHECK-NEXT: cneg w9, w9, le 335; CHECK-NEXT: ubfx w10, w10, #1, #15 336; CHECK-NEXT: madd w0, w10, w9, w8 337; CHECK-NEXT: ret 338 %a1 = load i16, i16* %a1_addr 339 %t3 = icmp sgt i16 %a1, %a2 ; signed 340 %t4 = select i1 %t3, i16 -1, i16 1 341 %t5 = select i1 %t3, i16 %a2, i16 %a1 342 %t6 = select i1 %t3, i16 %a1, i16 %a2 343 %t7 = sub i16 %t6, %t5 344 %t8 = lshr i16 %t7, 1 345 %t9 = mul nsw i16 %t8, %t4 ; signed 346 %a10 = add nsw i16 %t9, %a1 ; signed 347 ret i16 %a10 348} 349 350define i16 @scalar_i16_signed_reg_mem(i16 %a1, i16* %a2_addr) nounwind { 351; CHECK-LABEL: scalar_i16_signed_reg_mem: 352; CHECK: // %bb.0: 353; CHECK-NEXT: ldrsh w8, [x1] 354; CHECK-NEXT: sxth w9, w0 355; CHECK-NEXT: mov w10, #-1 356; CHECK-NEXT: cmp w9, w8 357; CHECK-NEXT: cneg w9, w10, le 358; CHECK-NEXT: csel w10, w8, w0, gt 359; CHECK-NEXT: csel w8, w0, w8, gt 360; CHECK-NEXT: sub w8, w8, w10 361; CHECK-NEXT: ubfx w8, w8, #1, #15 362; CHECK-NEXT: madd w0, w8, w9, w0 363; CHECK-NEXT: ret 364 %a2 = load i16, i16* %a2_addr 365 %t3 = icmp sgt i16 %a1, %a2 ; signed 366 %t4 = select i1 %t3, i16 -1, i16 1 367 %t5 = select i1 %t3, i16 %a2, i16 %a1 368 %t6 = select i1 %t3, i16 %a1, i16 %a2 369 %t7 = sub i16 %t6, %t5 370 %t8 = lshr i16 %t7, 1 371 %t9 = mul nsw i16 %t8, %t4 ; signed 372 %a10 = add nsw i16 %t9, %a1 ; signed 373 ret i16 %a10 374} 375 376define i16 @scalar_i16_signed_mem_mem(i16* %a1_addr, i16* %a2_addr) nounwind { 377; CHECK-LABEL: scalar_i16_signed_mem_mem: 378; CHECK: // %bb.0: 379; CHECK-NEXT: ldrsh w8, [x0] 380; CHECK-NEXT: ldrsh w9, [x1] 381; CHECK-NEXT: mov w10, #-1 382; CHECK-NEXT: cmp w8, w9 383; CHECK-NEXT: csel w11, w9, w8, gt 384; CHECK-NEXT: csel w9, w8, w9, gt 385; CHECK-NEXT: sub w9, w9, w11 386; CHECK-NEXT: cneg w10, w10, le 387; CHECK-NEXT: ubfx w9, w9, #1, #15 388; CHECK-NEXT: madd w0, w9, w10, w8 389; CHECK-NEXT: ret 390 %a1 = load i16, i16* %a1_addr 391 %a2 = load i16, i16* %a2_addr 392 %t3 = icmp sgt i16 %a1, %a2 ; signed 393 %t4 = select i1 %t3, i16 -1, i16 1 394 %t5 = select i1 %t3, i16 %a2, i16 %a1 395 %t6 = select i1 %t3, i16 %a1, i16 %a2 396 %t7 = sub i16 %t6, %t5 397 %t8 = lshr i16 %t7, 1 398 %t9 = mul nsw i16 %t8, %t4 ; signed 399 %a10 = add nsw i16 %t9, %a1 ; signed 400 ret i16 %a10 401} 402 403; ---------------------------------------------------------------------------- ; 404; 8-bit width 405; ---------------------------------------------------------------------------- ; 406 407; Values come from regs 408 409define i8 @scalar_i8_signed_reg_reg(i8 %a1, i8 %a2) nounwind { 410; CHECK-LABEL: scalar_i8_signed_reg_reg: 411; CHECK: // %bb.0: 412; CHECK-NEXT: sxtb w8, w0 413; CHECK-NEXT: mov w9, #-1 414; CHECK-NEXT: cmp w8, w1, sxtb 415; CHECK-NEXT: cneg w8, w9, le 416; CHECK-NEXT: csel w9, w1, w0, gt 417; CHECK-NEXT: csel w10, w0, w1, gt 418; CHECK-NEXT: sub w9, w10, w9 419; CHECK-NEXT: ubfx w9, w9, #1, #7 420; CHECK-NEXT: madd w0, w9, w8, w0 421; CHECK-NEXT: ret 422 %t3 = icmp sgt i8 %a1, %a2 ; signed 423 %t4 = select i1 %t3, i8 -1, i8 1 424 %t5 = select i1 %t3, i8 %a2, i8 %a1 425 %t6 = select i1 %t3, i8 %a1, i8 %a2 426 %t7 = sub i8 %t6, %t5 427 %t8 = lshr i8 %t7, 1 428 %t9 = mul nsw i8 %t8, %t4 ; signed 429 %a10 = add nsw i8 %t9, %a1 ; signed 430 ret i8 %a10 431} 432 433define i8 @scalar_i8_unsigned_reg_reg(i8 %a1, i8 %a2) nounwind { 434; CHECK-LABEL: scalar_i8_unsigned_reg_reg: 435; CHECK: // %bb.0: 436; CHECK-NEXT: and w8, w0, #0xff 437; CHECK-NEXT: mov w9, #-1 438; CHECK-NEXT: cmp w8, w1, uxtb 439; CHECK-NEXT: cneg w8, w9, ls 440; CHECK-NEXT: csel w9, w1, w0, hi 441; CHECK-NEXT: csel w10, w0, w1, hi 442; CHECK-NEXT: sub w9, w10, w9 443; CHECK-NEXT: ubfx w9, w9, #1, #7 444; CHECK-NEXT: madd w0, w9, w8, w0 445; CHECK-NEXT: ret 446 %t3 = icmp ugt i8 %a1, %a2 447 %t4 = select i1 %t3, i8 -1, i8 1 448 %t5 = select i1 %t3, i8 %a2, i8 %a1 449 %t6 = select i1 %t3, i8 %a1, i8 %a2 450 %t7 = sub i8 %t6, %t5 451 %t8 = lshr i8 %t7, 1 452 %t9 = mul i8 %t8, %t4 453 %a10 = add i8 %t9, %a1 454 ret i8 %a10 455} 456 457; Values are loaded. Only check signed case. 458 459define i8 @scalar_i8_signed_mem_reg(i8* %a1_addr, i8 %a2) nounwind { 460; CHECK-LABEL: scalar_i8_signed_mem_reg: 461; CHECK: // %bb.0: 462; CHECK-NEXT: ldrsb w8, [x0] 463; CHECK-NEXT: mov w9, #-1 464; CHECK-NEXT: cmp w8, w1, sxtb 465; CHECK-NEXT: csel w10, w1, w8, gt 466; CHECK-NEXT: csel w11, w8, w1, gt 467; CHECK-NEXT: sub w10, w11, w10 468; CHECK-NEXT: cneg w9, w9, le 469; CHECK-NEXT: ubfx w10, w10, #1, #7 470; CHECK-NEXT: madd w0, w10, w9, w8 471; CHECK-NEXT: ret 472 %a1 = load i8, i8* %a1_addr 473 %t3 = icmp sgt i8 %a1, %a2 ; signed 474 %t4 = select i1 %t3, i8 -1, i8 1 475 %t5 = select i1 %t3, i8 %a2, i8 %a1 476 %t6 = select i1 %t3, i8 %a1, i8 %a2 477 %t7 = sub i8 %t6, %t5 478 %t8 = lshr i8 %t7, 1 479 %t9 = mul nsw i8 %t8, %t4 ; signed 480 %a10 = add nsw i8 %t9, %a1 ; signed 481 ret i8 %a10 482} 483 484define i8 @scalar_i8_signed_reg_mem(i8 %a1, i8* %a2_addr) nounwind { 485; CHECK-LABEL: scalar_i8_signed_reg_mem: 486; CHECK: // %bb.0: 487; CHECK-NEXT: ldrsb w8, [x1] 488; CHECK-NEXT: sxtb w9, w0 489; CHECK-NEXT: mov w10, #-1 490; CHECK-NEXT: cmp w9, w8 491; CHECK-NEXT: cneg w9, w10, le 492; CHECK-NEXT: csel w10, w8, w0, gt 493; CHECK-NEXT: csel w8, w0, w8, gt 494; CHECK-NEXT: sub w8, w8, w10 495; CHECK-NEXT: ubfx w8, w8, #1, #7 496; CHECK-NEXT: madd w0, w8, w9, w0 497; CHECK-NEXT: ret 498 %a2 = load i8, i8* %a2_addr 499 %t3 = icmp sgt i8 %a1, %a2 ; signed 500 %t4 = select i1 %t3, i8 -1, i8 1 501 %t5 = select i1 %t3, i8 %a2, i8 %a1 502 %t6 = select i1 %t3, i8 %a1, i8 %a2 503 %t7 = sub i8 %t6, %t5 504 %t8 = lshr i8 %t7, 1 505 %t9 = mul nsw i8 %t8, %t4 ; signed 506 %a10 = add nsw i8 %t9, %a1 ; signed 507 ret i8 %a10 508} 509 510define i8 @scalar_i8_signed_mem_mem(i8* %a1_addr, i8* %a2_addr) nounwind { 511; CHECK-LABEL: scalar_i8_signed_mem_mem: 512; CHECK: // %bb.0: 513; CHECK-NEXT: ldrsb w8, [x0] 514; CHECK-NEXT: ldrsb w9, [x1] 515; CHECK-NEXT: mov w10, #-1 516; CHECK-NEXT: cmp w8, w9 517; CHECK-NEXT: csel w11, w9, w8, gt 518; CHECK-NEXT: csel w9, w8, w9, gt 519; CHECK-NEXT: sub w9, w9, w11 520; CHECK-NEXT: cneg w10, w10, le 521; CHECK-NEXT: ubfx w9, w9, #1, #7 522; CHECK-NEXT: madd w0, w9, w10, w8 523; CHECK-NEXT: ret 524 %a1 = load i8, i8* %a1_addr 525 %a2 = load i8, i8* %a2_addr 526 %t3 = icmp sgt i8 %a1, %a2 ; signed 527 %t4 = select i1 %t3, i8 -1, i8 1 528 %t5 = select i1 %t3, i8 %a2, i8 %a1 529 %t6 = select i1 %t3, i8 %a1, i8 %a2 530 %t7 = sub i8 %t6, %t5 531 %t8 = lshr i8 %t7, 1 532 %t9 = mul nsw i8 %t8, %t4 ; signed 533 %a10 = add nsw i8 %t9, %a1 ; signed 534 ret i8 %a10 535} 536