1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck -check-prefix=RV32I %s 3; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck -check-prefix=RV64I %s 4 5; 6; fixed avg(x,y) = sub(or(x,y),ashr(xor(x,y),1)) 7; 8; ext avg(x,y) = trunc(ashr(add(sext(x),sext(y),1),1)) 9; 10 11define i8 @test_fixed_i8(i8 %a0, i8 %a1) nounwind { 12; RV32I-LABEL: test_fixed_i8: 13; RV32I: # %bb.0: 14; RV32I-NEXT: slli a1, a1, 24 15; RV32I-NEXT: slli a0, a0, 24 16; RV32I-NEXT: srai a1, a1, 24 17; RV32I-NEXT: srai a0, a0, 24 18; RV32I-NEXT: add a0, a0, a1 19; RV32I-NEXT: addi a0, a0, 1 20; RV32I-NEXT: srai a0, a0, 1 21; RV32I-NEXT: ret 22; 23; RV64I-LABEL: test_fixed_i8: 24; RV64I: # %bb.0: 25; RV64I-NEXT: slli a1, a1, 56 26; RV64I-NEXT: slli a0, a0, 56 27; RV64I-NEXT: srai a1, a1, 56 28; RV64I-NEXT: srai a0, a0, 56 29; RV64I-NEXT: add a0, a0, a1 30; RV64I-NEXT: addi a0, a0, 1 31; RV64I-NEXT: srai a0, a0, 1 32; RV64I-NEXT: ret 33 %or = or i8 %a0, %a1 34 %xor = xor i8 %a0, %a1 35 %shift = ashr i8 %xor, 1 36 %res = sub i8 %or, %shift 37 ret i8 %res 38} 39 40define i8 @test_ext_i8(i8 %a0, i8 %a1) nounwind { 41; RV32I-LABEL: test_ext_i8: 42; RV32I: # %bb.0: 43; RV32I-NEXT: slli a1, a1, 24 44; RV32I-NEXT: slli a0, a0, 24 45; RV32I-NEXT: srai a1, a1, 24 46; RV32I-NEXT: srai a0, a0, 24 47; RV32I-NEXT: add a0, a0, a1 48; RV32I-NEXT: addi a0, a0, 1 49; RV32I-NEXT: srai a0, a0, 1 50; RV32I-NEXT: ret 51; 52; RV64I-LABEL: test_ext_i8: 53; RV64I: # %bb.0: 54; RV64I-NEXT: slli a1, a1, 56 55; RV64I-NEXT: slli a0, a0, 56 56; RV64I-NEXT: srai a1, a1, 56 57; RV64I-NEXT: srai a0, a0, 56 58; RV64I-NEXT: add a0, a0, a1 59; RV64I-NEXT: addi a0, a0, 1 60; RV64I-NEXT: srai a0, a0, 1 61; RV64I-NEXT: ret 62 %x0 = sext i8 %a0 to i16 63 %x1 = sext i8 %a1 to i16 64 %sum = add i16 %x0, %x1 65 %sum1 = add i16 %sum, 1 66 %shift = ashr i16 %sum1, 1 67 %res = trunc i16 %shift to i8 68 ret i8 %res 69} 70 71define i16 @test_fixed_i16(i16 %a0, i16 %a1) nounwind { 72; RV32I-LABEL: test_fixed_i16: 73; RV32I: # %bb.0: 74; RV32I-NEXT: slli a1, a1, 16 75; RV32I-NEXT: slli a0, a0, 16 76; RV32I-NEXT: srai a1, a1, 16 77; RV32I-NEXT: srai a0, a0, 16 78; RV32I-NEXT: add a0, a0, a1 79; RV32I-NEXT: addi a0, a0, 1 80; RV32I-NEXT: srai a0, a0, 1 81; RV32I-NEXT: ret 82; 83; RV64I-LABEL: test_fixed_i16: 84; RV64I: # %bb.0: 85; RV64I-NEXT: slli a1, a1, 48 86; RV64I-NEXT: slli a0, a0, 48 87; RV64I-NEXT: srai a1, a1, 48 88; RV64I-NEXT: srai a0, a0, 48 89; RV64I-NEXT: add a0, a0, a1 90; RV64I-NEXT: addi a0, a0, 1 91; RV64I-NEXT: srai a0, a0, 1 92; RV64I-NEXT: ret 93 %or = or i16 %a0, %a1 94 %xor = xor i16 %a0, %a1 95 %shift = ashr i16 %xor, 1 96 %res = sub i16 %or, %shift 97 ret i16 %res 98} 99 100define i16 @test_ext_i16(i16 %a0, i16 %a1) nounwind { 101; RV32I-LABEL: test_ext_i16: 102; RV32I: # %bb.0: 103; RV32I-NEXT: slli a1, a1, 16 104; RV32I-NEXT: slli a0, a0, 16 105; RV32I-NEXT: srai a1, a1, 16 106; RV32I-NEXT: srai a0, a0, 16 107; RV32I-NEXT: add a0, a0, a1 108; RV32I-NEXT: addi a0, a0, 1 109; RV32I-NEXT: srai a0, a0, 1 110; RV32I-NEXT: ret 111; 112; RV64I-LABEL: test_ext_i16: 113; RV64I: # %bb.0: 114; RV64I-NEXT: slli a1, a1, 48 115; RV64I-NEXT: slli a0, a0, 48 116; RV64I-NEXT: srai a1, a1, 48 117; RV64I-NEXT: srai a0, a0, 48 118; RV64I-NEXT: add a0, a0, a1 119; RV64I-NEXT: addi a0, a0, 1 120; RV64I-NEXT: srai a0, a0, 1 121; RV64I-NEXT: ret 122 %x0 = sext i16 %a0 to i32 123 %x1 = sext i16 %a1 to i32 124 %sum = add i32 %x0, %x1 125 %sum1 = add i32 %sum, 1 126 %shift = ashr i32 %sum1, 1 127 %res = trunc i32 %shift to i16 128 ret i16 %res 129} 130 131define i32 @test_fixed_i32(i32 %a0, i32 %a1) nounwind { 132; RV32I-LABEL: test_fixed_i32: 133; RV32I: # %bb.0: 134; RV32I-NEXT: or a2, a0, a1 135; RV32I-NEXT: xor a0, a0, a1 136; RV32I-NEXT: srai a0, a0, 1 137; RV32I-NEXT: sub a0, a2, a0 138; RV32I-NEXT: ret 139; 140; RV64I-LABEL: test_fixed_i32: 141; RV64I: # %bb.0: 142; RV64I-NEXT: sext.w a1, a1 143; RV64I-NEXT: sext.w a0, a0 144; RV64I-NEXT: add a0, a0, a1 145; RV64I-NEXT: addi a0, a0, 1 146; RV64I-NEXT: srai a0, a0, 1 147; RV64I-NEXT: ret 148 %or = or i32 %a0, %a1 149 %xor = xor i32 %a1, %a0 150 %shift = ashr i32 %xor, 1 151 %res = sub i32 %or, %shift 152 ret i32 %res 153} 154 155define i32 @test_ext_i32(i32 %a0, i32 %a1) nounwind { 156; RV32I-LABEL: test_ext_i32: 157; RV32I: # %bb.0: 158; RV32I-NEXT: or a2, a0, a1 159; RV32I-NEXT: xor a0, a0, a1 160; RV32I-NEXT: srai a0, a0, 1 161; RV32I-NEXT: sub a0, a2, a0 162; RV32I-NEXT: ret 163; 164; RV64I-LABEL: test_ext_i32: 165; RV64I: # %bb.0: 166; RV64I-NEXT: sext.w a1, a1 167; RV64I-NEXT: sext.w a0, a0 168; RV64I-NEXT: add a0, a0, a1 169; RV64I-NEXT: addi a0, a0, 1 170; RV64I-NEXT: srai a0, a0, 1 171; RV64I-NEXT: ret 172 %x0 = sext i32 %a0 to i64 173 %x1 = sext i32 %a1 to i64 174 %sum = add i64 %x0, %x1 175 %sum1 = add i64 %sum, 1 176 %shift = ashr i64 %sum1, 1 177 %res = trunc i64 %shift to i32 178 ret i32 %res 179} 180 181define i64 @test_fixed_i64(i64 %a0, i64 %a1) nounwind { 182; RV32I-LABEL: test_fixed_i64: 183; RV32I: # %bb.0: 184; RV32I-NEXT: or a4, a1, a3 185; RV32I-NEXT: xor a1, a1, a3 186; RV32I-NEXT: xor a3, a0, a2 187; RV32I-NEXT: or a0, a0, a2 188; RV32I-NEXT: srai a2, a1, 1 189; RV32I-NEXT: slli a1, a1, 31 190; RV32I-NEXT: srli a3, a3, 1 191; RV32I-NEXT: sub a4, a4, a2 192; RV32I-NEXT: or a3, a3, a1 193; RV32I-NEXT: sltu a1, a0, a3 194; RV32I-NEXT: sub a1, a4, a1 195; RV32I-NEXT: sub a0, a0, a3 196; RV32I-NEXT: ret 197; 198; RV64I-LABEL: test_fixed_i64: 199; RV64I: # %bb.0: 200; RV64I-NEXT: or a2, a0, a1 201; RV64I-NEXT: xor a0, a0, a1 202; RV64I-NEXT: srai a0, a0, 1 203; RV64I-NEXT: sub a0, a2, a0 204; RV64I-NEXT: ret 205 %or = or i64 %a0, %a1 206 %xor = xor i64 %a1, %a0 207 %shift = ashr i64 %xor, 1 208 %res = sub i64 %or, %shift 209 ret i64 %res 210} 211 212define i64 @test_ext_i64(i64 %a0, i64 %a1) nounwind { 213; RV32I-LABEL: test_ext_i64: 214; RV32I: # %bb.0: 215; RV32I-NEXT: or a4, a1, a3 216; RV32I-NEXT: xor a1, a1, a3 217; RV32I-NEXT: xor a3, a0, a2 218; RV32I-NEXT: or a0, a0, a2 219; RV32I-NEXT: srai a2, a1, 1 220; RV32I-NEXT: slli a1, a1, 31 221; RV32I-NEXT: srli a3, a3, 1 222; RV32I-NEXT: sub a4, a4, a2 223; RV32I-NEXT: or a3, a3, a1 224; RV32I-NEXT: sltu a1, a0, a3 225; RV32I-NEXT: sub a1, a4, a1 226; RV32I-NEXT: sub a0, a0, a3 227; RV32I-NEXT: ret 228; 229; RV64I-LABEL: test_ext_i64: 230; RV64I: # %bb.0: 231; RV64I-NEXT: or a2, a0, a1 232; RV64I-NEXT: xor a0, a0, a1 233; RV64I-NEXT: srai a0, a0, 1 234; RV64I-NEXT: sub a0, a2, a0 235; RV64I-NEXT: ret 236 %x0 = sext i64 %a0 to i128 237 %x1 = sext i64 %a1 to i128 238 %sum = add i128 %x0, %x1 239 %sum1 = add i128 %sum, 1 240 %shift = ashr i128 %sum1, 1 241 %res = trunc i128 %shift to i64 242 ret i64 %res 243} 244