294 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=riscv32 \3; RUN: | FileCheck %s --check-prefixes=CHECK,RV32,RV32I4; RUN: llc < %s -mtriple=riscv64 \5; RUN: | FileCheck %s --check-prefixes=CHECK,RV64,RV64I6; RUN: llc < %s -mtriple=riscv32 -mattr=+zbb \7; RUN: | FileCheck %s --check-prefixes=CHECK,RV32,RV32ZBB8; RUN: llc < %s -mtriple=riscv64 -mattr=+zbb \9; RUN: | FileCheck %s --check-prefixes=CHECK,RV64,RV64ZBB10 11; Compare if negative and select of constants where one constant is zero.12define i32 @neg_sel_constants(i32 signext %a) {13; RV32-LABEL: neg_sel_constants:14; RV32: # %bb.0:15; RV32-NEXT: srai a0, a0, 3116; RV32-NEXT: andi a0, a0, 517; RV32-NEXT: ret18;19; RV64-LABEL: neg_sel_constants:20; RV64: # %bb.0:21; RV64-NEXT: srai a0, a0, 6322; RV64-NEXT: andi a0, a0, 523; RV64-NEXT: ret24 %tmp.1 = icmp slt i32 %a, 025 %retval = select i1 %tmp.1, i32 5, i32 026 ret i32 %retval27}28 29; Compare if negative and select of constants where one constant is zero and the30; other is a single bit.31define i32 @neg_sel_special_constant(i32 signext %a) {32; RV32-LABEL: neg_sel_special_constant:33; RV32: # %bb.0:34; RV32-NEXT: srli a0, a0, 3135; RV32-NEXT: slli a0, a0, 936; RV32-NEXT: ret37;38; RV64-LABEL: neg_sel_special_constant:39; RV64: # %bb.0:40; RV64-NEXT: srliw a0, a0, 3141; RV64-NEXT: slli a0, a0, 942; RV64-NEXT: ret43 %tmp.1 = icmp slt i32 %a, 044 %retval = select i1 %tmp.1, i32 512, i32 045 ret i32 %retval46}47 48; Compare if negative and select variable or zero.49define i32 @neg_sel_variable_and_zero(i32 signext %a, i32 signext %b) {50; CHECK-LABEL: neg_sel_variable_and_zero:51; CHECK: # %bb.0:52; CHECK-NEXT: srai a0, a0, 3153; CHECK-NEXT: and a0, a0, a154; CHECK-NEXT: ret55 %tmp.1 = icmp slt i32 %a, 056 %retval = select i1 %tmp.1, i32 %b, i32 057 ret i32 %retval58}59 60; Compare if not positive and select the same variable as being compared:61; smin(a, 0).62define i32 @not_pos_sel_same_variable(i32 signext %a) {63; CHECK-LABEL: not_pos_sel_same_variable:64; CHECK: # %bb.0:65; CHECK-NEXT: srai a1, a0, 3166; CHECK-NEXT: and a0, a1, a067; CHECK-NEXT: ret68 %tmp = icmp slt i32 %a, 169 %min = select i1 %tmp, i32 %a, i32 070 ret i32 %min71}72 73; Flipping the comparison condition can be handled by getting the bitwise not of74; the sign mask.75; TODO: We aren't doing a good job of this.76 77; Compare if positive and select of constants where one constant is zero.78define i32 @pos_sel_constants(i32 signext %a) {79; RV32-LABEL: pos_sel_constants:80; RV32: # %bb.0:81; RV32-NEXT: srli a0, a0, 3182; RV32-NEXT: addi a0, a0, -183; RV32-NEXT: andi a0, a0, 584; RV32-NEXT: ret85;86; RV64-LABEL: pos_sel_constants:87; RV64: # %bb.0:88; RV64-NEXT: srli a0, a0, 6389; RV64-NEXT: addi a0, a0, -190; RV64-NEXT: andi a0, a0, 591; RV64-NEXT: ret92 %tmp.1 = icmp sgt i32 %a, -193 %retval = select i1 %tmp.1, i32 5, i32 094 ret i32 %retval95}96 97; Compare if positive and select of constants where one constant is zero and the98; other is a single bit.99; TODO: Why do RV32 and RV64 generate different code? RV64 uses more registers,100; but the addi isn't part of the dependency chain of %a so may be faster.101define i32 @pos_sel_special_constant(i32 signext %a) {102; RV32-LABEL: pos_sel_special_constant:103; RV32: # %bb.0:104; RV32-NEXT: not a0, a0105; RV32-NEXT: srli a0, a0, 31106; RV32-NEXT: slli a0, a0, 9107; RV32-NEXT: ret108;109; RV64-LABEL: pos_sel_special_constant:110; RV64: # %bb.0:111; RV64-NEXT: srli a0, a0, 63112; RV64-NEXT: xori a0, a0, 1113; RV64-NEXT: slli a0, a0, 9114; RV64-NEXT: ret115 %tmp.1 = icmp sgt i32 %a, -1116 %retval = select i1 %tmp.1, i32 512, i32 0117 ret i32 %retval118}119 120; Compare if positive and select variable or zero.121define i32 @pos_sel_variable_and_zero(i32 signext %a, i32 signext %b) {122; RV32I-LABEL: pos_sel_variable_and_zero:123; RV32I: # %bb.0:124; RV32I-NEXT: srli a0, a0, 31125; RV32I-NEXT: addi a0, a0, -1126; RV32I-NEXT: and a0, a0, a1127; RV32I-NEXT: ret128;129; RV64I-LABEL: pos_sel_variable_and_zero:130; RV64I: # %bb.0:131; RV64I-NEXT: srli a0, a0, 63132; RV64I-NEXT: addi a0, a0, -1133; RV64I-NEXT: and a0, a0, a1134; RV64I-NEXT: ret135;136; RV32ZBB-LABEL: pos_sel_variable_and_zero:137; RV32ZBB: # %bb.0:138; RV32ZBB-NEXT: srai a0, a0, 31139; RV32ZBB-NEXT: andn a0, a1, a0140; RV32ZBB-NEXT: ret141;142; RV64ZBB-LABEL: pos_sel_variable_and_zero:143; RV64ZBB: # %bb.0:144; RV64ZBB-NEXT: srai a0, a0, 31145; RV64ZBB-NEXT: andn a0, a1, a0146; RV64ZBB-NEXT: ret147 %tmp.1 = icmp sgt i32 %a, -1148 %retval = select i1 %tmp.1, i32 %b, i32 0149 ret i32 %retval150}151 152; Compare if not negative or zero and select the same variable as being153; compared: smax(a, 0).154define i32 @not_neg_sel_same_variable(i32 signext %a) {155; RV32I-LABEL: not_neg_sel_same_variable:156; RV32I: # %bb.0:157; RV32I-NEXT: sgtz a1, a0158; RV32I-NEXT: neg a1, a1159; RV32I-NEXT: and a0, a1, a0160; RV32I-NEXT: ret161;162; RV64I-LABEL: not_neg_sel_same_variable:163; RV64I: # %bb.0:164; RV64I-NEXT: sgtz a1, a0165; RV64I-NEXT: neg a1, a1166; RV64I-NEXT: and a0, a1, a0167; RV64I-NEXT: ret168;169; RV32ZBB-LABEL: not_neg_sel_same_variable:170; RV32ZBB: # %bb.0:171; RV32ZBB-NEXT: max a0, a0, zero172; RV32ZBB-NEXT: ret173;174; RV64ZBB-LABEL: not_neg_sel_same_variable:175; RV64ZBB: # %bb.0:176; RV64ZBB-NEXT: max a0, a0, zero177; RV64ZBB-NEXT: ret178 %tmp = icmp sgt i32 %a, 0179 %min = select i1 %tmp, i32 %a, i32 0180 ret i32 %min181}182 183; ret = (x-y) > 0 ? x-y : 0184define i32 @sub_clamp_zero(i32 signext %x, i32 signext %y) {185; RV32I-LABEL: sub_clamp_zero:186; RV32I: # %bb.0:187; RV32I-NEXT: sub a0, a0, a1188; RV32I-NEXT: sgtz a1, a0189; RV32I-NEXT: neg a1, a1190; RV32I-NEXT: and a0, a1, a0191; RV32I-NEXT: ret192;193; RV64I-LABEL: sub_clamp_zero:194; RV64I: # %bb.0:195; RV64I-NEXT: subw a0, a0, a1196; RV64I-NEXT: sgtz a1, a0197; RV64I-NEXT: neg a1, a1198; RV64I-NEXT: and a0, a1, a0199; RV64I-NEXT: ret200;201; RV32ZBB-LABEL: sub_clamp_zero:202; RV32ZBB: # %bb.0:203; RV32ZBB-NEXT: sub a0, a0, a1204; RV32ZBB-NEXT: max a0, a0, zero205; RV32ZBB-NEXT: ret206;207; RV64ZBB-LABEL: sub_clamp_zero:208; RV64ZBB: # %bb.0:209; RV64ZBB-NEXT: subw a0, a0, a1210; RV64ZBB-NEXT: max a0, a0, zero211; RV64ZBB-NEXT: ret212 %sub = sub nsw i32 %x, %y213 %cmp = icmp sgt i32 %sub, 0214 %sel = select i1 %cmp, i32 %sub, i32 0215 ret i32 %sel216}217 218define i8 @sel_shift_bool_i8(i1 %t) {219; RV32-LABEL: sel_shift_bool_i8:220; RV32: # %bb.0:221; RV32-NEXT: slli a0, a0, 31222; RV32-NEXT: srai a0, a0, 31223; RV32-NEXT: andi a0, a0, -128224; RV32-NEXT: ret225;226; RV64-LABEL: sel_shift_bool_i8:227; RV64: # %bb.0:228; RV64-NEXT: slli a0, a0, 63229; RV64-NEXT: srai a0, a0, 63230; RV64-NEXT: andi a0, a0, -128231; RV64-NEXT: ret232 %shl = select i1 %t, i8 128, i8 0233 ret i8 %shl234}235 236define i16 @sel_shift_bool_i16(i1 %t) {237; CHECK-LABEL: sel_shift_bool_i16:238; CHECK: # %bb.0:239; CHECK-NEXT: andi a0, a0, 1240; CHECK-NEXT: slli a0, a0, 7241; CHECK-NEXT: ret242 %shl = select i1 %t, i16 128, i16 0243 ret i16 %shl244}245 246define i32 @sel_shift_bool_i32(i1 %t) {247; CHECK-LABEL: sel_shift_bool_i32:248; CHECK: # %bb.0:249; CHECK-NEXT: andi a0, a0, 1250; CHECK-NEXT: slli a0, a0, 6251; CHECK-NEXT: ret252 %shl = select i1 %t, i32 64, i32 0253 ret i32 %shl254}255 256define i64 @sel_shift_bool_i64(i1 %t) {257; RV32-LABEL: sel_shift_bool_i64:258; RV32: # %bb.0:259; RV32-NEXT: andi a0, a0, 1260; RV32-NEXT: slli a0, a0, 16261; RV32-NEXT: li a1, 0262; RV32-NEXT: ret263;264; RV64-LABEL: sel_shift_bool_i64:265; RV64: # %bb.0:266; RV64-NEXT: andi a0, a0, 1267; RV64-NEXT: slli a0, a0, 16268; RV64-NEXT: ret269 %shl = select i1 %t, i64 65536, i64 0270 ret i64 %shl271}272 273define i64 @sraiw_andi(i32 signext %0, i32 signext %1) nounwind {274; RV32-LABEL: sraiw_andi:275; RV32: # %bb.0: # %entry276; RV32-NEXT: add a0, a0, a1277; RV32-NEXT: srai a0, a0, 2278; RV32-NEXT: srli a0, a0, 29279; RV32-NEXT: li a1, 0280; RV32-NEXT: ret281;282; RV64-LABEL: sraiw_andi:283; RV64: # %bb.0: # %entry284; RV64-NEXT: add a0, a0, a1285; RV64-NEXT: sraiw a0, a0, 31286; RV64-NEXT: andi a0, a0, 7287; RV64-NEXT: ret288entry:289 %3 = add i32 %0, %1290 %4 = icmp sgt i32 %3, -1291 %5 = select i1 %4, i64 0, i64 7292 ret i64 %5293}294