1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32I %s 4; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IF %s 6; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV32IBT %s 8; RUN: llc -mtriple=riscv32 -mattr=+f,+experimental-zbt -verify-machineinstrs < %s \ 9; RUN: | FileCheck -check-prefix=RV32IFBT %s 10; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 11; RUN: | FileCheck -check-prefix=RV64I %s 12; RUN: llc -mtriple=riscv64 -mattr=+f,+d -verify-machineinstrs < %s \ 13; RUN: | FileCheck -check-prefix=RV64IFD %s 14; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 15; RUN: | FileCheck -check-prefix=RV64IBT %s 16; RUN: llc -mtriple=riscv64 -mattr=+f,+d,+experimental-zbt -verify-machineinstrs < %s \ 17; RUN: | FileCheck -check-prefix=RV64IFDBT %s 18 19;; This tests how good we are at materialising constants using `select`. The aim 20;; is that we do so without a branch if possible (at the moment our lowering of 21;; select always introduces a branch). 22;; 23;; Currently the hook `convertSelectOfConstantsToMath` only is useful when the 24;; constants are either 1 away from each other, or one is a power of two and 25;; the other is zero. 26 27define signext i32 @select_const_int_easy(i1 zeroext %a) nounwind { 28; RV32I-LABEL: select_const_int_easy: 29; RV32I: # %bb.0: 30; RV32I-NEXT: ret 31; 32; RV32IF-LABEL: select_const_int_easy: 33; RV32IF: # %bb.0: 34; RV32IF-NEXT: ret 35; 36; RV32IBT-LABEL: select_const_int_easy: 37; RV32IBT: # %bb.0: 38; RV32IBT-NEXT: ret 39; 40; RV32IFBT-LABEL: select_const_int_easy: 41; RV32IFBT: # %bb.0: 42; RV32IFBT-NEXT: ret 43; 44; RV64I-LABEL: select_const_int_easy: 45; RV64I: # %bb.0: 46; RV64I-NEXT: ret 47; 48; RV64IFD-LABEL: select_const_int_easy: 49; RV64IFD: # %bb.0: 50; RV64IFD-NEXT: ret 51; 52; RV64IBT-LABEL: select_const_int_easy: 53; RV64IBT: # %bb.0: 54; RV64IBT-NEXT: ret 55; 56; RV64IFDBT-LABEL: select_const_int_easy: 57; RV64IFDBT: # %bb.0: 58; RV64IFDBT-NEXT: ret 59 %1 = select i1 %a, i32 1, i32 0 60 ret i32 %1 61} 62 63define signext i32 @select_const_int_one_away(i1 zeroext %a) nounwind { 64; RV32I-LABEL: select_const_int_one_away: 65; RV32I: # %bb.0: 66; RV32I-NEXT: li a1, 4 67; RV32I-NEXT: sub a0, a1, a0 68; RV32I-NEXT: ret 69; 70; RV32IF-LABEL: select_const_int_one_away: 71; RV32IF: # %bb.0: 72; RV32IF-NEXT: li a1, 4 73; RV32IF-NEXT: sub a0, a1, a0 74; RV32IF-NEXT: ret 75; 76; RV32IBT-LABEL: select_const_int_one_away: 77; RV32IBT: # %bb.0: 78; RV32IBT-NEXT: li a1, 4 79; RV32IBT-NEXT: sub a0, a1, a0 80; RV32IBT-NEXT: ret 81; 82; RV32IFBT-LABEL: select_const_int_one_away: 83; RV32IFBT: # %bb.0: 84; RV32IFBT-NEXT: li a1, 4 85; RV32IFBT-NEXT: sub a0, a1, a0 86; RV32IFBT-NEXT: ret 87; 88; RV64I-LABEL: select_const_int_one_away: 89; RV64I: # %bb.0: 90; RV64I-NEXT: li a1, 4 91; RV64I-NEXT: sub a0, a1, a0 92; RV64I-NEXT: ret 93; 94; RV64IFD-LABEL: select_const_int_one_away: 95; RV64IFD: # %bb.0: 96; RV64IFD-NEXT: li a1, 4 97; RV64IFD-NEXT: sub a0, a1, a0 98; RV64IFD-NEXT: ret 99; 100; RV64IBT-LABEL: select_const_int_one_away: 101; RV64IBT: # %bb.0: 102; RV64IBT-NEXT: li a1, 4 103; RV64IBT-NEXT: sub a0, a1, a0 104; RV64IBT-NEXT: ret 105; 106; RV64IFDBT-LABEL: select_const_int_one_away: 107; RV64IFDBT: # %bb.0: 108; RV64IFDBT-NEXT: li a1, 4 109; RV64IFDBT-NEXT: sub a0, a1, a0 110; RV64IFDBT-NEXT: ret 111 %1 = select i1 %a, i32 3, i32 4 112 ret i32 %1 113} 114 115define signext i32 @select_const_int_pow2_zero(i1 zeroext %a) nounwind { 116; RV32I-LABEL: select_const_int_pow2_zero: 117; RV32I: # %bb.0: 118; RV32I-NEXT: slli a0, a0, 2 119; RV32I-NEXT: ret 120; 121; RV32IF-LABEL: select_const_int_pow2_zero: 122; RV32IF: # %bb.0: 123; RV32IF-NEXT: slli a0, a0, 2 124; RV32IF-NEXT: ret 125; 126; RV32IBT-LABEL: select_const_int_pow2_zero: 127; RV32IBT: # %bb.0: 128; RV32IBT-NEXT: slli a0, a0, 2 129; RV32IBT-NEXT: ret 130; 131; RV32IFBT-LABEL: select_const_int_pow2_zero: 132; RV32IFBT: # %bb.0: 133; RV32IFBT-NEXT: slli a0, a0, 2 134; RV32IFBT-NEXT: ret 135; 136; RV64I-LABEL: select_const_int_pow2_zero: 137; RV64I: # %bb.0: 138; RV64I-NEXT: slli a0, a0, 2 139; RV64I-NEXT: ret 140; 141; RV64IFD-LABEL: select_const_int_pow2_zero: 142; RV64IFD: # %bb.0: 143; RV64IFD-NEXT: slli a0, a0, 2 144; RV64IFD-NEXT: ret 145; 146; RV64IBT-LABEL: select_const_int_pow2_zero: 147; RV64IBT: # %bb.0: 148; RV64IBT-NEXT: slli a0, a0, 2 149; RV64IBT-NEXT: ret 150; 151; RV64IFDBT-LABEL: select_const_int_pow2_zero: 152; RV64IFDBT: # %bb.0: 153; RV64IFDBT-NEXT: slli a0, a0, 2 154; RV64IFDBT-NEXT: ret 155 %1 = select i1 %a, i32 4, i32 0 156 ret i32 %1 157} 158 159define signext i32 @select_const_int_harder(i1 zeroext %a) nounwind { 160; RV32I-LABEL: select_const_int_harder: 161; RV32I: # %bb.0: 162; RV32I-NEXT: mv a1, a0 163; RV32I-NEXT: li a0, 6 164; RV32I-NEXT: bnez a1, .LBB3_2 165; RV32I-NEXT: # %bb.1: 166; RV32I-NEXT: li a0, 38 167; RV32I-NEXT: .LBB3_2: 168; RV32I-NEXT: ret 169; 170; RV32IF-LABEL: select_const_int_harder: 171; RV32IF: # %bb.0: 172; RV32IF-NEXT: mv a1, a0 173; RV32IF-NEXT: li a0, 6 174; RV32IF-NEXT: bnez a1, .LBB3_2 175; RV32IF-NEXT: # %bb.1: 176; RV32IF-NEXT: li a0, 38 177; RV32IF-NEXT: .LBB3_2: 178; RV32IF-NEXT: ret 179; 180; RV32IBT-LABEL: select_const_int_harder: 181; RV32IBT: # %bb.0: 182; RV32IBT-NEXT: li a1, 38 183; RV32IBT-NEXT: li a2, 6 184; RV32IBT-NEXT: cmov a0, a0, a2, a1 185; RV32IBT-NEXT: ret 186; 187; RV32IFBT-LABEL: select_const_int_harder: 188; RV32IFBT: # %bb.0: 189; RV32IFBT-NEXT: li a1, 38 190; RV32IFBT-NEXT: li a2, 6 191; RV32IFBT-NEXT: cmov a0, a0, a2, a1 192; RV32IFBT-NEXT: ret 193; 194; RV64I-LABEL: select_const_int_harder: 195; RV64I: # %bb.0: 196; RV64I-NEXT: mv a1, a0 197; RV64I-NEXT: li a0, 6 198; RV64I-NEXT: bnez a1, .LBB3_2 199; RV64I-NEXT: # %bb.1: 200; RV64I-NEXT: li a0, 38 201; RV64I-NEXT: .LBB3_2: 202; RV64I-NEXT: ret 203; 204; RV64IFD-LABEL: select_const_int_harder: 205; RV64IFD: # %bb.0: 206; RV64IFD-NEXT: mv a1, a0 207; RV64IFD-NEXT: li a0, 6 208; RV64IFD-NEXT: bnez a1, .LBB3_2 209; RV64IFD-NEXT: # %bb.1: 210; RV64IFD-NEXT: li a0, 38 211; RV64IFD-NEXT: .LBB3_2: 212; RV64IFD-NEXT: ret 213; 214; RV64IBT-LABEL: select_const_int_harder: 215; RV64IBT: # %bb.0: 216; RV64IBT-NEXT: li a1, 38 217; RV64IBT-NEXT: li a2, 6 218; RV64IBT-NEXT: cmov a0, a0, a2, a1 219; RV64IBT-NEXT: ret 220; 221; RV64IFDBT-LABEL: select_const_int_harder: 222; RV64IFDBT: # %bb.0: 223; RV64IFDBT-NEXT: li a1, 38 224; RV64IFDBT-NEXT: li a2, 6 225; RV64IFDBT-NEXT: cmov a0, a0, a2, a1 226; RV64IFDBT-NEXT: ret 227 %1 = select i1 %a, i32 6, i32 38 228 ret i32 %1 229} 230 231define float @select_const_fp(i1 zeroext %a) nounwind { 232; RV32I-LABEL: select_const_fp: 233; RV32I: # %bb.0: 234; RV32I-NEXT: mv a1, a0 235; RV32I-NEXT: lui a0, 263168 236; RV32I-NEXT: bnez a1, .LBB4_2 237; RV32I-NEXT: # %bb.1: 238; RV32I-NEXT: lui a0, 264192 239; RV32I-NEXT: .LBB4_2: 240; RV32I-NEXT: ret 241; 242; RV32IF-LABEL: select_const_fp: 243; RV32IF: # %bb.0: 244; RV32IF-NEXT: bnez a0, .LBB4_2 245; RV32IF-NEXT: # %bb.1: 246; RV32IF-NEXT: lui a0, %hi(.LCPI4_0) 247; RV32IF-NEXT: flw ft0, %lo(.LCPI4_0)(a0) 248; RV32IF-NEXT: fmv.x.w a0, ft0 249; RV32IF-NEXT: ret 250; RV32IF-NEXT: .LBB4_2: 251; RV32IF-NEXT: lui a0, %hi(.LCPI4_1) 252; RV32IF-NEXT: flw ft0, %lo(.LCPI4_1)(a0) 253; RV32IF-NEXT: fmv.x.w a0, ft0 254; RV32IF-NEXT: ret 255; 256; RV32IBT-LABEL: select_const_fp: 257; RV32IBT: # %bb.0: 258; RV32IBT-NEXT: lui a1, 264192 259; RV32IBT-NEXT: lui a2, 263168 260; RV32IBT-NEXT: cmov a0, a0, a2, a1 261; RV32IBT-NEXT: ret 262; 263; RV32IFBT-LABEL: select_const_fp: 264; RV32IFBT: # %bb.0: 265; RV32IFBT-NEXT: bnez a0, .LBB4_2 266; RV32IFBT-NEXT: # %bb.1: 267; RV32IFBT-NEXT: lui a0, %hi(.LCPI4_0) 268; RV32IFBT-NEXT: flw ft0, %lo(.LCPI4_0)(a0) 269; RV32IFBT-NEXT: fmv.x.w a0, ft0 270; RV32IFBT-NEXT: ret 271; RV32IFBT-NEXT: .LBB4_2: 272; RV32IFBT-NEXT: lui a0, %hi(.LCPI4_1) 273; RV32IFBT-NEXT: flw ft0, %lo(.LCPI4_1)(a0) 274; RV32IFBT-NEXT: fmv.x.w a0, ft0 275; RV32IFBT-NEXT: ret 276; 277; RV64I-LABEL: select_const_fp: 278; RV64I: # %bb.0: 279; RV64I-NEXT: mv a1, a0 280; RV64I-NEXT: lui a0, 263168 281; RV64I-NEXT: bnez a1, .LBB4_2 282; RV64I-NEXT: # %bb.1: 283; RV64I-NEXT: lui a0, 264192 284; RV64I-NEXT: .LBB4_2: 285; RV64I-NEXT: ret 286; 287; RV64IFD-LABEL: select_const_fp: 288; RV64IFD: # %bb.0: 289; RV64IFD-NEXT: bnez a0, .LBB4_2 290; RV64IFD-NEXT: # %bb.1: 291; RV64IFD-NEXT: lui a0, %hi(.LCPI4_0) 292; RV64IFD-NEXT: flw ft0, %lo(.LCPI4_0)(a0) 293; RV64IFD-NEXT: fmv.x.w a0, ft0 294; RV64IFD-NEXT: ret 295; RV64IFD-NEXT: .LBB4_2: 296; RV64IFD-NEXT: lui a0, %hi(.LCPI4_1) 297; RV64IFD-NEXT: flw ft0, %lo(.LCPI4_1)(a0) 298; RV64IFD-NEXT: fmv.x.w a0, ft0 299; RV64IFD-NEXT: ret 300; 301; RV64IBT-LABEL: select_const_fp: 302; RV64IBT: # %bb.0: 303; RV64IBT-NEXT: lui a1, 264192 304; RV64IBT-NEXT: lui a2, 263168 305; RV64IBT-NEXT: cmov a0, a0, a2, a1 306; RV64IBT-NEXT: ret 307; 308; RV64IFDBT-LABEL: select_const_fp: 309; RV64IFDBT: # %bb.0: 310; RV64IFDBT-NEXT: bnez a0, .LBB4_2 311; RV64IFDBT-NEXT: # %bb.1: 312; RV64IFDBT-NEXT: lui a0, %hi(.LCPI4_0) 313; RV64IFDBT-NEXT: flw ft0, %lo(.LCPI4_0)(a0) 314; RV64IFDBT-NEXT: fmv.x.w a0, ft0 315; RV64IFDBT-NEXT: ret 316; RV64IFDBT-NEXT: .LBB4_2: 317; RV64IFDBT-NEXT: lui a0, %hi(.LCPI4_1) 318; RV64IFDBT-NEXT: flw ft0, %lo(.LCPI4_1)(a0) 319; RV64IFDBT-NEXT: fmv.x.w a0, ft0 320; RV64IFDBT-NEXT: ret 321 %1 = select i1 %a, float 3.0, float 4.0 322 ret float %1 323} 324