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