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