1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-gnu-linux -o - | FileCheck %s 3 4; These tests make sure that the `cmp` instruction is rendered with an 5; instruction that checks the sign bit of the original unextended data 6; (%in) instead of the sign bit of the sign extended one that is 7; created by the type legalization process. 8; 9; The tests are subdivided in tests that determine the sign bit 10; looking through a `sign_extend_inreg` and tests that determine the 11; sign bit looking through a `sign_extend`. 12 13define i32 @f_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind { 14; CHECK-LABEL: f_i8_sign_extend_inreg: 15; CHECK: // %bb.0: // %entry 16; CHECK-NEXT: sxtb w8, w0 17; CHECK-NEXT: cmp w8, #0 18; CHECK-NEXT: csel w8, w1, w2, ge 19; CHECK-NEXT: add w0, w8, w0, uxtb 20; CHECK-NEXT: ret 21entry: 22 %cmp = icmp sgt i8 %in, -1 23 %ext = zext i8 %in to i32 24 br i1 %cmp, label %A, label %B 25 26A: 27 %retA = add i32 %ext, %a 28 ret i32 %retA 29 30B: 31 %retB = add i32 %ext, %b 32 ret i32 %retB 33} 34 35define i32 @f_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind { 36; CHECK-LABEL: f_i16_sign_extend_inreg: 37; CHECK: // %bb.0: // %entry 38; CHECK-NEXT: sxth w8, w0 39; CHECK-NEXT: cmp w8, #0 40; CHECK-NEXT: csel w8, w1, w2, ge 41; CHECK-NEXT: add w0, w8, w0, uxth 42; CHECK-NEXT: ret 43entry: 44 %cmp = icmp sgt i16 %in, -1 45 %ext = zext i16 %in to i32 46 br i1 %cmp, label %A, label %B 47 48A: 49 %retA = add i32 %ext, %a 50 ret i32 %retA 51 52B: 53 %retB = add i32 %ext, %b 54 ret i32 %retB 55} 56 57define i64 @f_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind { 58; CHECK-LABEL: f_i32_sign_extend_inreg: 59; CHECK: // %bb.0: // %entry 60; CHECK-NEXT: cmp w0, #0 61; CHECK-NEXT: csel x8, x1, x2, ge 62; CHECK-NEXT: add x0, x8, w0, uxtw 63; CHECK-NEXT: ret 64entry: 65 %cmp = icmp sgt i32 %in, -1 66 %ext = zext i32 %in to i64 67 br i1 %cmp, label %A, label %B 68 69A: 70 %retA = add i64 %ext, %a 71 ret i64 %retA 72 73B: 74 %retB = add i64 %ext, %b 75 ret i64 %retB 76} 77 78define i32 @g_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind { 79; CHECK-LABEL: g_i8_sign_extend_inreg: 80; CHECK: // %bb.0: // %entry 81; CHECK-NEXT: sxtb w8, w0 82; CHECK-NEXT: cmp w8, #0 83; CHECK-NEXT: csel w8, w1, w2, lt 84; CHECK-NEXT: add w0, w8, w0, uxtb 85; CHECK-NEXT: ret 86entry: 87 %cmp = icmp slt i8 %in, 0 88 %ext = zext i8 %in to i32 89 br i1 %cmp, label %A, label %B 90 91A: 92 %retA = add i32 %ext, %a 93 ret i32 %retA 94 95B: 96 %retB = add i32 %ext, %b 97 ret i32 %retB 98} 99 100define i32 @g_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind { 101; CHECK-LABEL: g_i16_sign_extend_inreg: 102; CHECK: // %bb.0: // %entry 103; CHECK-NEXT: sxth w8, w0 104; CHECK-NEXT: cmp w8, #0 105; CHECK-NEXT: csel w8, w1, w2, lt 106; CHECK-NEXT: add w0, w8, w0, uxth 107; CHECK-NEXT: ret 108entry: 109 %cmp = icmp slt i16 %in, 0 110 %ext = zext i16 %in to i32 111 br i1 %cmp, label %A, label %B 112 113A: 114 %retA = add i32 %ext, %a 115 ret i32 %retA 116 117B: 118 %retB = add i32 %ext, %b 119 ret i32 %retB 120} 121 122define i64 @g_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind { 123; CHECK-LABEL: g_i32_sign_extend_inreg: 124; CHECK: // %bb.0: // %entry 125; CHECK-NEXT: cmp w0, #0 126; CHECK-NEXT: csel x8, x1, x2, lt 127; CHECK-NEXT: add x0, x8, w0, uxtw 128; CHECK-NEXT: ret 129entry: 130 %cmp = icmp slt i32 %in, 0 131 %ext = zext i32 %in to i64 132 br i1 %cmp, label %A, label %B 133 134A: 135 %retA = add i64 %ext, %a 136 ret i64 %retA 137 138B: 139 %retB = add i64 %ext, %b 140 ret i64 %retB 141} 142 143define i64 @f_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind { 144; CHECK-LABEL: f_i32_sign_extend_i64: 145; CHECK: // %bb.0: // %entry 146; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 147; CHECK-NEXT: sxtw x8, w0 148; CHECK-NEXT: cmp x8, #0 149; CHECK-NEXT: csel x8, x1, x2, ge 150; CHECK-NEXT: add x0, x8, w0, uxtw 151; CHECK-NEXT: ret 152entry: 153 %inext = sext i32 %in to i64 154 %cmp = icmp sgt i64 %inext, -1 155 %ext = zext i32 %in to i64 156 br i1 %cmp, label %A, label %B 157 158A: 159 %retA = add i64 %ext, %a 160 ret i64 %retA 161 162B: 163 %retB = add i64 %ext, %b 164 ret i64 %retB 165} 166 167define i64 @g_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind { 168; CHECK-LABEL: g_i32_sign_extend_i64: 169; CHECK: // %bb.0: // %entry 170; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 171; CHECK-NEXT: sxtw x8, w0 172; CHECK-NEXT: cmp x8, #0 173; CHECK-NEXT: csel x8, x1, x2, lt 174; CHECK-NEXT: add x0, x8, w0, uxtw 175; CHECK-NEXT: ret 176entry: 177 %inext = sext i32 %in to i64 178 %cmp = icmp slt i64 %inext, 0 179 %ext = zext i32 %in to i64 180 br i1 %cmp, label %A, label %B 181 182A: 183 %retA = add i64 %ext, %a 184 ret i64 %retA 185 186B: 187 %retB = add i64 %ext, %b 188 ret i64 %retB 189} 190