1; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s 2 3; 4; Test that we only use the sign/zero extend in the address calculation when 5; necessary. 6; 7; SHIFT 8; 9define i64 @load_addr_shift_zext1(i32 zeroext %a, i64 %b) { 10; CHECK-LABEL: load_addr_shift_zext1 11; CHECK: ldr {{x[0-9]+}}, [x1, x0, lsl #3] 12 %1 = zext i32 %a to i64 13 %2 = shl i64 %1, 3 14 %3 = add i64 %b, %2 15 %4 = inttoptr i64 %3 to i64* 16 %5 = load i64* %4 17 ret i64 %5 18} 19 20define i64 @load_addr_shift_zext2(i32 signext %a, i64 %b) { 21; CHECK-LABEL: load_addr_shift_zext2 22; CHECK: ldr {{x[0-9]+}}, [x1, w0, uxtw #3{{\]}} 23 %1 = zext i32 %a to i64 24 %2 = shl i64 %1, 3 25 %3 = add i64 %b, %2 26 %4 = inttoptr i64 %3 to i64* 27 %5 = load i64* %4 28 ret i64 %5 29} 30 31define i64 @load_addr_shift_sext1(i32 signext %a, i64 %b) { 32; CHECK-LABEL: load_addr_shift_sext1 33; CHECK: ldr {{x[0-9]+}}, [x1, x0, lsl #3] 34 %1 = sext i32 %a to i64 35 %2 = shl i64 %1, 3 36 %3 = add i64 %b, %2 37 %4 = inttoptr i64 %3 to i64* 38 %5 = load i64* %4 39 ret i64 %5 40} 41 42define i64 @load_addr_shift_sext2(i32 zeroext %a, i64 %b) { 43; CHECK-LABEL: load_addr_shift_sext2 44; CHECK: ldr {{x[0-9]+}}, [x1, w0, sxtw #3] 45 %1 = sext i32 %a to i64 46 %2 = shl i64 %1, 3 47 %3 = add i64 %b, %2 48 %4 = inttoptr i64 %3 to i64* 49 %5 = load i64* %4 50 ret i64 %5 51} 52 53; 54; MUL 55; 56define i64 @load_addr_mul_zext1(i32 zeroext %a, i64 %b) { 57; CHECK-LABEL: load_addr_mul_zext1 58; CHECK: ldr {{x[0-9]+}}, [x1, x0, lsl #3] 59 %1 = zext i32 %a to i64 60 %2 = mul i64 %1, 8 61 %3 = add i64 %b, %2 62 %4 = inttoptr i64 %3 to i64* 63 %5 = load i64* %4 64 ret i64 %5 65} 66 67define i64 @load_addr_mul_zext2(i32 signext %a, i64 %b) { 68; CHECK-LABEL: load_addr_mul_zext2 69; CHECK: ldr {{x[0-9]+}}, [x1, w0, uxtw #3] 70 %1 = zext i32 %a to i64 71 %2 = mul i64 %1, 8 72 %3 = add i64 %b, %2 73 %4 = inttoptr i64 %3 to i64* 74 %5 = load i64* %4 75 ret i64 %5 76} 77 78define i64 @load_addr_mul_sext1(i32 signext %a, i64 %b) { 79; CHECK-LABEL: load_addr_mul_sext1 80; CHECK: ldr {{x[0-9]+}}, [x1, x0, lsl #3] 81 %1 = sext i32 %a to i64 82 %2 = mul i64 %1, 8 83 %3 = add i64 %b, %2 84 %4 = inttoptr i64 %3 to i64* 85 %5 = load i64* %4 86 ret i64 %5 87} 88 89define i64 @load_addr_mul_sext2(i32 zeroext %a, i64 %b) { 90; CHECK-LABEL: load_addr_mul_sext2 91; CHECK: ldr {{x[0-9]+}}, [x1, w0, sxtw #3] 92 %1 = sext i32 %a to i64 93 %2 = mul i64 %1, 8 94 %3 = add i64 %b, %2 95 %4 = inttoptr i64 %3 to i64* 96 %5 = load i64* %4 97 ret i64 %5 98} 99 100; Test folding of the sign-/zero-extend into the load instruction. 101define i32 @load_zext_i8_to_i32(i8* %a) { 102; CHECK-LABEL: load_zext_i8_to_i32 103; CHECK: ldrb w0, [x0] 104; CHECK-NOT: uxtb 105 %1 = load i8* %a 106 %2 = zext i8 %1 to i32 107 ret i32 %2 108} 109 110define i32 @load_zext_i16_to_i32(i16* %a) { 111; CHECK-LABEL: load_zext_i16_to_i32 112; CHECK: ldrh w0, [x0] 113; CHECK-NOT: uxth 114 %1 = load i16* %a 115 %2 = zext i16 %1 to i32 116 ret i32 %2 117} 118 119define i64 @load_zext_i8_to_i64(i8* %a) { 120; CHECK-LABEL: load_zext_i8_to_i64 121; CHECK: ldrb w0, [x0] 122; CHECK-NOT: uxtb 123 %1 = load i8* %a 124 %2 = zext i8 %1 to i64 125 ret i64 %2 126} 127 128define i64 @load_zext_i16_to_i64(i16* %a) { 129; CHECK-LABEL: load_zext_i16_to_i64 130; CHECK: ldrh w0, [x0] 131; CHECK-NOT: uxth 132 %1 = load i16* %a 133 %2 = zext i16 %1 to i64 134 ret i64 %2 135} 136 137define i64 @load_zext_i32_to_i64(i32* %a) { 138; CHECK-LABEL: load_zext_i32_to_i64 139; CHECK: ldr w0, [x0] 140; CHECK-NOT: uxtw 141 %1 = load i32* %a 142 %2 = zext i32 %1 to i64 143 ret i64 %2 144} 145 146define i32 @load_sext_i8_to_i32(i8* %a) { 147; CHECK-LABEL: load_sext_i8_to_i32 148; CHECK: ldrsb w0, [x0] 149; CHECK-NOT: sxtb 150 %1 = load i8* %a 151 %2 = sext i8 %1 to i32 152 ret i32 %2 153} 154 155define i32 @load_sext_i16_to_i32(i16* %a) { 156; CHECK-LABEL: load_sext_i16_to_i32 157; CHECK: ldrsh w0, [x0] 158; CHECK-NOT: sxth 159 %1 = load i16* %a 160 %2 = sext i16 %1 to i32 161 ret i32 %2 162} 163 164define i64 @load_sext_i8_to_i64(i8* %a) { 165; CHECK-LABEL: load_sext_i8_to_i64 166; CHECK: ldrsb w0, [x0] 167; CHECK-NOT: sxtb 168 %1 = load i8* %a 169 %2 = sext i8 %1 to i64 170 ret i64 %2 171} 172 173define i64 @load_sext_i16_to_i64(i16* %a) { 174; CHECK-LABEL: load_sext_i16_to_i64 175; CHECK: ldrsh w0, [x0] 176; CHECK-NOT: sxth 177 %1 = load i16* %a 178 %2 = sext i16 %1 to i64 179 ret i64 %2 180} 181 182define i64 @load_sext_i32_to_i64(i32* %a) { 183; CHECK-LABEL: load_sext_i32_to_i64 184; CHECK: ldrsw x0, [x0] 185; CHECK-NOT: sxtw 186 %1 = load i32* %a 187 %2 = sext i32 %1 to i64 188 ret i64 %2 189} 190 191