brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.7 KiB · 6056145 Raw
676 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1030 -passes=instcombine -S < %s | FileCheck %s3 4; test unary5 6define float @hoist_fneg_f32(float %arg) {7; CHECK-LABEL: define float @hoist_fneg_f32(8; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {9; CHECK-NEXT:  [[BB:.*:]]10; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])11; CHECK-NEXT:    [[RFL:%.*]] = fneg float [[TMP0]]12; CHECK-NEXT:    ret float [[RFL]]13;14bb:15  %val = fneg float %arg16  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)17  ret float %rfl18}19 20define double @hoist_fneg_f64(double %arg) {21; CHECK-LABEL: define double @hoist_fneg_f64(22; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR0]] {23; CHECK-NEXT:  [[BB:.*:]]24; CHECK-NEXT:    [[TMP0:%.*]] = call double @llvm.amdgcn.readfirstlane.f64(double [[ARG]])25; CHECK-NEXT:    [[RFL:%.*]] = fneg double [[TMP0]]26; CHECK-NEXT:    ret double [[RFL]]27;28bb:29  %val = fneg double %arg30  %rfl = call double @llvm.amdgcn.readfirstlane.f64(double %val)31  ret double %rfl32}33 34; test casts35 36define i32 @hoist_trunc(i64 %arg) {37; CHECK-LABEL: define i32 @hoist_trunc(38; CHECK-SAME: i64 [[ARG:%.*]]) #[[ATTR0]] {39; CHECK-NEXT:  [[BB:.*:]]40; CHECK-NEXT:    [[RFL:%.*]] = call i64 @llvm.amdgcn.readfirstlane.i64(i64 [[ARG]])41; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[RFL]] to i3242; CHECK-NEXT:    ret i32 [[TMP0]]43;44bb:45  %val = trunc i64 %arg to i3246  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)47  ret i32 %rfl48}49 50define i64 @hoist_zext(i32 %arg) {51; CHECK-LABEL: define i64 @hoist_zext(52; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {53; CHECK-NEXT:  [[BB:.*:]]54; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])55; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[RFL]] to i6456; CHECK-NEXT:    ret i64 [[TMP0]]57;58bb:59  %val = zext i32 %arg to i6460  %rfl = call i64 @llvm.amdgcn.readfirstlane.i64(i64 %val)61  ret i64 %rfl62}63 64define i64 @hoist_sext(i32 %arg) {65; CHECK-LABEL: define i64 @hoist_sext(66; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {67; CHECK-NEXT:  [[BB:.*:]]68; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])69; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[RFL]] to i6470; CHECK-NEXT:    ret i64 [[TMP0]]71;72bb:73  %val = zext i32 %arg to i6474  %rfl = call i64 @llvm.amdgcn.readfirstlane.i64(i64 %val)75  ret i64 %rfl76}77 78define i32 @hoist_fptoui(float %arg) {79; CHECK-LABEL: define i32 @hoist_fptoui(80; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {81; CHECK-NEXT:  [[BB:.*:]]82; CHECK-NEXT:    [[RFL:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])83; CHECK-NEXT:    [[TMP0:%.*]] = fptoui float [[RFL]] to i3284; CHECK-NEXT:    ret i32 [[TMP0]]85;86bb:87  %val = fptoui float %arg to i3288  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)89  ret i32 %rfl90}91 92define i32 @hoist_fptosi(float %arg) {93; CHECK-LABEL: define i32 @hoist_fptosi(94; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {95; CHECK-NEXT:  [[BB:.*:]]96; CHECK-NEXT:    [[RFL:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])97; CHECK-NEXT:    [[TMP0:%.*]] = fptosi float [[RFL]] to i3298; CHECK-NEXT:    ret i32 [[TMP0]]99;100bb:101  %val = fptosi float %arg to i32102  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)103  ret i32 %rfl104}105 106define float @hoist_uitofp(i32 %arg) {107; CHECK-LABEL: define float @hoist_uitofp(108; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {109; CHECK-NEXT:  [[BB:.*:]]110; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])111; CHECK-NEXT:    [[TMP0:%.*]] = uitofp i32 [[RFL]] to float112; CHECK-NEXT:    ret float [[TMP0]]113;114bb:115  %val = uitofp i32 %arg to float116  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)117  ret float %rfl118}119 120define float @hoist_sitofp(i32 %arg) {121; CHECK-LABEL: define float @hoist_sitofp(122; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {123; CHECK-NEXT:  [[BB:.*:]]124; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])125; CHECK-NEXT:    [[TMP0:%.*]] = sitofp i32 [[RFL]] to float126; CHECK-NEXT:    ret float [[TMP0]]127;128bb:129  %val = sitofp i32 %arg to float130  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)131  ret float %rfl132}133 134define float @hoist_fptrunc(double %arg) {135; CHECK-LABEL: define float @hoist_fptrunc(136; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR0]] {137; CHECK-NEXT:  [[BB:.*:]]138; CHECK-NEXT:    [[RFL:%.*]] = call double @llvm.amdgcn.readfirstlane.f64(double [[ARG]])139; CHECK-NEXT:    [[TMP0:%.*]] = fptrunc double [[RFL]] to float140; CHECK-NEXT:    ret float [[TMP0]]141;142bb:143  %val = fptrunc double %arg to float144  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)145  ret float %rfl146}147 148define float @hoist_fpext(half %arg) {149; CHECK-LABEL: define float @hoist_fpext(150; CHECK-SAME: half [[ARG:%.*]]) #[[ATTR0]] {151; CHECK-NEXT:  [[BB:.*:]]152; CHECK-NEXT:    [[RFL:%.*]] = call half @llvm.amdgcn.readfirstlane.f16(half [[ARG]])153; CHECK-NEXT:    [[TMP0:%.*]] = fpext half [[RFL]] to float154; CHECK-NEXT:    ret float [[TMP0]]155;156bb:157  %val = fpext half %arg to float158  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)159  ret float %rfl160}161 162define i64 @hoist_ptrtoint(ptr %arg) {163; CHECK-LABEL: define i64 @hoist_ptrtoint(164; CHECK-SAME: ptr [[ARG:%.*]]) #[[ATTR0]] {165; CHECK-NEXT:  [[BB:.*:]]166; CHECK-NEXT:    [[RFL:%.*]] = call ptr @llvm.amdgcn.readfirstlane.p0(ptr [[ARG]])167; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[RFL]] to i64168; CHECK-NEXT:    ret i64 [[TMP0]]169;170bb:171  %val = ptrtoint ptr %arg to i64172  %rfl = call i64 @llvm.amdgcn.readfirstlane.i64(i64 %val)173  ret i64 %rfl174}175 176define ptr @hoist_inttoptr(i64 %arg) {177; CHECK-LABEL: define ptr @hoist_inttoptr(178; CHECK-SAME: i64 [[ARG:%.*]]) #[[ATTR0]] {179; CHECK-NEXT:  [[BB:.*:]]180; CHECK-NEXT:    [[RFL:%.*]] = call i64 @llvm.amdgcn.readfirstlane.i64(i64 [[ARG]])181; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[RFL]] to ptr182; CHECK-NEXT:    ret ptr [[TMP0]]183;184bb:185  %val = inttoptr i64 %arg to ptr186  %rfl = call ptr @llvm.amdgcn.readfirstlane.p0(ptr %val)187  ret ptr %rfl188}189 190define float @hoist_bitcast(i32 %arg) {191; CHECK-LABEL: define float @hoist_bitcast(192; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {193; CHECK-NEXT:  [[BB:.*:]]194; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])195; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 [[RFL]] to float196; CHECK-NEXT:    ret float [[TMP0]]197;198bb:199  %val = bitcast i32 %arg to float200  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)201  ret float %rfl202}203 204define ptr addrspace(1) @hoist_addrspacecast(ptr addrspace(0) %arg) {205; CHECK-LABEL: define ptr addrspace(1) @hoist_addrspacecast(206; CHECK-SAME: ptr [[ARG:%.*]]) #[[ATTR0]] {207; CHECK-NEXT:  [[BB:.*:]]208; CHECK-NEXT:    [[RFL:%.*]] = call ptr @llvm.amdgcn.readfirstlane.p0(ptr [[ARG]])209; CHECK-NEXT:    [[TMP0:%.*]] = addrspacecast ptr [[RFL]] to ptr addrspace(1)210; CHECK-NEXT:    ret ptr addrspace(1) [[TMP0]]211;212bb:213  %val = addrspacecast ptr addrspace(0) %arg to ptr addrspace(1)214  %rfl = call ptr addrspace(1) @llvm.amdgcn.readfirstlane.p1(ptr addrspace(1) %val)215  ret ptr addrspace(1) %rfl216}217 218; test binary i32219 220define i32 @hoist_add_i32(i32 %arg) {221; CHECK-LABEL: define i32 @hoist_add_i32(222; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {223; CHECK-NEXT:  [[BB:.*:]]224; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])225; CHECK-NEXT:    [[RFL:%.*]] = add i32 [[TMP0]], 16777215226; CHECK-NEXT:    ret i32 [[RFL]]227;228bb:229  %val = add i32 %arg, 16777215230  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)231  ret i32 %rfl232}233 234define float @hoist_fadd_f32(float %arg) {235; CHECK-LABEL: define float @hoist_fadd_f32(236; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {237; CHECK-NEXT:  [[BB:.*:]]238; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])239; CHECK-NEXT:    [[RFL:%.*]] = fadd float [[TMP0]], 1.280000e+02240; CHECK-NEXT:    ret float [[RFL]]241;242bb:243  %val = fadd float %arg, 128.0244  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)245  ret float %rfl246}247 248define i32 @hoist_sub_i32(i32 %arg) {249; CHECK-LABEL: define i32 @hoist_sub_i32(250; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {251; CHECK-NEXT:  [[BB:.*:]]252; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])253; CHECK-NEXT:    [[RFL:%.*]] = add i32 [[TMP0]], -16777215254; CHECK-NEXT:    ret i32 [[RFL]]255;256bb:257  %val = sub i32 %arg, 16777215258  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)259  ret i32 %rfl260}261 262define float @hoist_fsub_f32(float %arg) {263; CHECK-LABEL: define float @hoist_fsub_f32(264; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {265; CHECK-NEXT:  [[BB:.*:]]266; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])267; CHECK-NEXT:    [[RFL:%.*]] = fadd float [[TMP0]], -1.280000e+02268; CHECK-NEXT:    ret float [[RFL]]269;270bb:271  %val = fsub float %arg, 128.0272  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)273  ret float %rfl274}275 276define i32 @hoist_mul_i32(i32 %arg) {277; CHECK-LABEL: define i32 @hoist_mul_i32(278; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {279; CHECK-NEXT:  [[BB:.*:]]280; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])281; CHECK-NEXT:    [[RFL:%.*]] = mul i32 [[TMP0]], 16777215282; CHECK-NEXT:    ret i32 [[RFL]]283;284bb:285  %val = mul i32 %arg, 16777215286  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)287  ret i32 %rfl288}289 290define float @hoist_fmul_f32(float %arg) {291; CHECK-LABEL: define float @hoist_fmul_f32(292; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {293; CHECK-NEXT:  [[BB:.*:]]294; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])295; CHECK-NEXT:    [[RFL:%.*]] = fmul float [[TMP0]], 1.280000e+02296; CHECK-NEXT:    ret float [[RFL]]297;298bb:299  %val = fmul float %arg, 128.0300  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)301  ret float %rfl302}303 304define i32 @hoist_udiv_i32(i32 %arg) {305; CHECK-LABEL: define i32 @hoist_udiv_i32(306; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {307; CHECK-NEXT:  [[BB:.*:]]308; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])309; CHECK-NEXT:    [[RFL:%.*]] = udiv i32 [[TMP0]], 16777215310; CHECK-NEXT:    ret i32 [[RFL]]311;312bb:313  %val = udiv i32 %arg, 16777215314  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)315  ret i32 %rfl316}317 318define i32 @hoist_sdiv_i32(i32 %arg) {319; CHECK-LABEL: define i32 @hoist_sdiv_i32(320; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {321; CHECK-NEXT:  [[BB:.*:]]322; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])323; CHECK-NEXT:    [[RFL:%.*]] = sdiv i32 [[TMP0]], 16777215324; CHECK-NEXT:    ret i32 [[RFL]]325;326bb:327  %val = sdiv i32 %arg, 16777215328  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)329  ret i32 %rfl330}331 332define float @hoist_fdiv_f32(float %arg) {333; CHECK-LABEL: define float @hoist_fdiv_f32(334; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {335; CHECK-NEXT:  [[BB:.*:]]336; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])337; CHECK-NEXT:    [[RFL:%.*]] = fmul float [[TMP0]], 7.812500e-03338; CHECK-NEXT:    ret float [[RFL]]339;340bb:341  %val = fdiv float %arg, 128.0342  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)343  ret float %rfl344}345 346define i32 @hoist_urem_i32(i32 %arg) {347; CHECK-LABEL: define i32 @hoist_urem_i32(348; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {349; CHECK-NEXT:  [[BB:.*:]]350; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])351; CHECK-NEXT:    [[RFL:%.*]] = urem i32 [[TMP0]], 16777215352; CHECK-NEXT:    ret i32 [[RFL]]353;354bb:355  %val = urem i32 %arg, 16777215356  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)357  ret i32 %rfl358}359 360define i32 @hoist_srem_i32(i32 %arg) {361; CHECK-LABEL: define i32 @hoist_srem_i32(362; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {363; CHECK-NEXT:  [[BB:.*:]]364; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])365; CHECK-NEXT:    [[RFL:%.*]] = srem i32 [[TMP0]], 16777215366; CHECK-NEXT:    ret i32 [[RFL]]367;368bb:369  %val = srem i32 %arg, 16777215370  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)371  ret i32 %rfl372}373 374define float @hoist_frem_f32(float %arg) {375; CHECK-LABEL: define float @hoist_frem_f32(376; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {377; CHECK-NEXT:  [[BB:.*:]]378; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])379; CHECK-NEXT:    [[RFL:%.*]] = frem float [[TMP0]], 1.280000e+02380; CHECK-NEXT:    ret float [[RFL]]381;382bb:383  %val = frem float %arg, 128.0384  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)385  ret float %rfl386}387 388define i32 @hoist_shl_i32(i32 %arg) {389; CHECK-LABEL: define i32 @hoist_shl_i32(390; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {391; CHECK-NEXT:  [[BB:.*:]]392; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])393; CHECK-NEXT:    [[RFL:%.*]] = shl i32 [[TMP0]], 4394; CHECK-NEXT:    ret i32 [[RFL]]395;396bb:397  %val = shl i32 %arg, 4398  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)399  ret i32 %rfl400}401 402define i32 @hoist_lshr_i32(i32 %arg) {403; CHECK-LABEL: define i32 @hoist_lshr_i32(404; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {405; CHECK-NEXT:  [[BB:.*:]]406; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])407; CHECK-NEXT:    [[RFL:%.*]] = lshr i32 [[TMP0]], 4408; CHECK-NEXT:    ret i32 [[RFL]]409;410bb:411  %val = lshr i32 %arg, 4412  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)413  ret i32 %rfl414}415 416define i32 @hoist_ashr_i32(i32 %arg) {417; CHECK-LABEL: define i32 @hoist_ashr_i32(418; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {419; CHECK-NEXT:  [[BB:.*:]]420; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])421; CHECK-NEXT:    [[RFL:%.*]] = ashr i32 [[TMP0]], 4422; CHECK-NEXT:    ret i32 [[RFL]]423;424bb:425  %val = ashr i32 %arg, 4426  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)427  ret i32 %rfl428}429 430 431define i32 @hoist_and_i32(i32 %arg) {432; CHECK-LABEL: define i32 @hoist_and_i32(433; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {434; CHECK-NEXT:  [[BB:.*:]]435; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])436; CHECK-NEXT:    [[RFL:%.*]] = and i32 [[TMP0]], 16777215437; CHECK-NEXT:    ret i32 [[RFL]]438;439bb:440  %val = and i32 %arg, 16777215441  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)442  ret i32 %rfl443}444 445define i32 @hoist_or_i32(i32 %arg) {446; CHECK-LABEL: define i32 @hoist_or_i32(447; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {448; CHECK-NEXT:  [[BB:.*:]]449; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])450; CHECK-NEXT:    [[RFL:%.*]] = or i32 [[TMP0]], 16777215451; CHECK-NEXT:    ret i32 [[RFL]]452;453bb:454  %val = or i32 %arg, 16777215455  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)456  ret i32 %rfl457}458 459define i32 @hoist_xor_i32(i32 %arg) {460; CHECK-LABEL: define i32 @hoist_xor_i32(461; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {462; CHECK-NEXT:  [[BB:.*:]]463; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])464; CHECK-NEXT:    [[RFL:%.*]] = xor i32 [[TMP0]], 16777215465; CHECK-NEXT:    ret i32 [[RFL]]466;467bb:468  %val = xor i32 %arg, 16777215469  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)470  ret i32 %rfl471}472 473; test binary i64474 475define i64 @hoist_and_i64(i64 %arg) {476; CHECK-LABEL: define i64 @hoist_and_i64(477; CHECK-SAME: i64 [[ARG:%.*]]) #[[ATTR0]] {478; CHECK-NEXT:  [[BB:.*:]]479; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.amdgcn.readfirstlane.i64(i64 [[ARG]])480; CHECK-NEXT:    [[RFL:%.*]] = and i64 [[TMP0]], 16777215481; CHECK-NEXT:    ret i64 [[RFL]]482;483bb:484  %val = and i64 %arg, 16777215485  %rfl = call i64 @llvm.amdgcn.readfirstlane.i32(i64 %val)486  ret i64 %rfl487}488 489define double @hoist_fadd_f64(double %arg) {490; CHECK-LABEL: define double @hoist_fadd_f64(491; CHECK-SAME: double [[ARG:%.*]]) #[[ATTR0]] {492; CHECK-NEXT:  [[BB:.*:]]493; CHECK-NEXT:    [[TMP0:%.*]] = call double @llvm.amdgcn.readfirstlane.f64(double [[ARG]])494; CHECK-NEXT:    [[RFL:%.*]] = fadd double [[TMP0]], 1.280000e+02495; CHECK-NEXT:    ret double [[RFL]]496;497bb:498  %val = fadd double %arg, 128.0499  %rfl = call double @llvm.amdgcn.readfirstlane.f64(double %val)500  ret double %rfl501}502 503; test constant on LHS504 505define i32 @hoist_sub_i32_lhs(i32 %arg) {506; CHECK-LABEL: define i32 @hoist_sub_i32_lhs(507; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {508; CHECK-NEXT:  [[BB:.*:]]509; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])510; CHECK-NEXT:    [[RFL:%.*]] = sub i32 16777215, [[TMP0]]511; CHECK-NEXT:    ret i32 [[RFL]]512;513bb:514  %val = sub i32 16777215, %arg515  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)516  ret i32 %rfl517}518 519define float @hoist_fsub_f32_lhs(float %arg) {520; CHECK-LABEL: define float @hoist_fsub_f32_lhs(521; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR0]] {522; CHECK-NEXT:  [[BB:.*:]]523; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.readfirstlane.f32(float [[ARG]])524; CHECK-NEXT:    [[RFL:%.*]] = fsub float 1.280000e+02, [[TMP0]]525; CHECK-NEXT:    ret float [[RFL]]526;527bb:528  %val = fsub float 128.0, %arg529  %rfl = call float @llvm.amdgcn.readfirstlane.f32(float %val)530  ret float %rfl531}532 533; test other operand is trivially uniform534 535define i32 @hoist_add_i32_trivially_uniform_rhs(i32 %arg, i32 %v.other) {536; CHECK-LABEL: define i32 @hoist_add_i32_trivially_uniform_rhs(537; CHECK-SAME: i32 [[ARG:%.*]], i32 [[V_OTHER:%.*]]) #[[ATTR0]] {538; CHECK-NEXT:  [[BB:.*:]]539; CHECK-NEXT:    [[OTHER:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V_OTHER]])540; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])541; CHECK-NEXT:    [[RFL:%.*]] = add i32 [[TMP0]], [[OTHER]]542; CHECK-NEXT:    ret i32 [[RFL]]543;544bb:545  %other = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %v.other)546  %val = add i32 %arg, %other547  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)548  ret i32 %rfl549}550 551define i32 @hoist_add_i32_trivially_uniform_lhs(i32 %arg, i32 %v.other) {552; CHECK-LABEL: define i32 @hoist_add_i32_trivially_uniform_lhs(553; CHECK-SAME: i32 [[ARG:%.*]], i32 [[V_OTHER:%.*]]) #[[ATTR0]] {554; CHECK-NEXT:  [[BB:.*:]]555; CHECK-NEXT:    [[OTHER:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[V_OTHER]])556; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])557; CHECK-NEXT:    [[RFL:%.*]] = sub i32 [[OTHER]], [[TMP0]]558; CHECK-NEXT:    ret i32 [[RFL]]559;560bb:561  %other = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %v.other)562  %val = sub i32 %other, %arg563  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)564  ret i32 %rfl565}566 567; test multiple iterations568 569define i32 @hoist_multiple_times(i32 %arg) {570; CHECK-LABEL: define i32 @hoist_multiple_times(571; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR0]] {572; CHECK-NEXT:  [[BB:.*:]]573; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]])574; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[TMP0]], 2575; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 16777215, [[TMP1]]576; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], 4242577; CHECK-NEXT:    [[RFL:%.*]] = add i32 [[TMP3]], 6578; CHECK-NEXT:    ret i32 [[RFL]]579;580bb:581  %val.0 = shl i32 %arg, 2582  %val.1 = sub i32 16777215, %val.0583  %val.2 = xor i32 %val.1, 4242584  %val.3 = add i32 %val.2, 6585  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val.3)586  ret i32 %rfl587}588 589; test cases where hoisting isn't possible590 591define i32 @cross_block_hoisting(i1 %cond, i32 %arg) {592; CHECK-LABEL: define i32 @cross_block_hoisting(593; CHECK-SAME: i1 [[COND:%.*]], i32 [[ARG:%.*]]) #[[ATTR0]] {594; CHECK-NEXT:  [[BB:.*]]:595; CHECK-NEXT:    [[VAL:%.*]] = add i32 [[ARG]], 16777215596; CHECK-NEXT:    br i1 [[COND]], label %[[THEN:.*]], label %[[END:.*]]597; CHECK:       [[THEN]]:598; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[VAL]])599; CHECK-NEXT:    br label %[[END]]600; CHECK:       [[END]]:601; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[RFL]], %[[THEN]] ], [ [[VAL]], %[[BB]] ]602; CHECK-NEXT:    ret i32 [[RES]]603;604bb:605  %val = add i32 %arg, 16777215606  br i1 %cond, label %then, label %end607 608then:609  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)610  br label %end611 612end:613  %res = phi i32 [%rfl, %then], [%val, %bb]614  ret i32 %res615}616 617define i32 @operand_is_instr(i32 %arg, ptr %src) {618; CHECK-LABEL: define i32 @operand_is_instr(619; CHECK-SAME: i32 [[ARG:%.*]], ptr [[SRC:%.*]]) #[[ATTR0]] {620; CHECK-NEXT:  [[BB:.*:]]621; CHECK-NEXT:    [[OTHER:%.*]] = load i32, ptr [[SRC]], align 4622; CHECK-NEXT:    [[VAL:%.*]] = add i32 [[ARG]], [[OTHER]]623; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[VAL]])624; CHECK-NEXT:    ret i32 [[RFL]]625;626bb:627  %other = load i32, ptr %src628  %val = add i32 %arg, %other629  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)630  ret i32 %rfl631}632 633define i32 @operand_is_arg(i32 %arg, i32 %other) {634; CHECK-LABEL: define i32 @operand_is_arg(635; CHECK-SAME: i32 [[ARG:%.*]], i32 [[OTHER:%.*]]) #[[ATTR0]] {636; CHECK-NEXT:  [[BB:.*:]]637; CHECK-NEXT:    [[VAL:%.*]] = add i32 [[ARG]], [[OTHER]]638; CHECK-NEXT:    [[RFL:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[VAL]])639; CHECK-NEXT:    ret i32 [[RFL]]640;641bb:642  %val = add i32 %arg, %other643  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val)644  ret i32 %rfl645}646 647; test that convergence tokens are preserved648 649define i32 @hoist_preserves_convergence_token(i1 %cond, i32 %arg) convergent {650; CHECK-LABEL: define i32 @hoist_preserves_convergence_token(651; CHECK-SAME: i1 [[COND:%.*]], i32 [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {652; CHECK-NEXT:  [[BB:.*]]:653; CHECK-NEXT:    [[ENTRY:%.*]] = call token @llvm.experimental.convergence.entry()654; CHECK-NEXT:    br i1 [[COND]], label %[[THEN:.*]], label %[[END:.*]]655; CHECK:       [[THEN]]:656; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.amdgcn.readfirstlane.i32(i32 [[ARG]]) [ "convergencectrl"(token [[ENTRY]]) ]657; CHECK-NEXT:    [[RFL:%.*]] = add i32 [[TMP0]], 16777215658; CHECK-NEXT:    br label %[[END]]659; CHECK:       [[END]]:660; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[RFL]], %[[THEN]] ], [ [[ARG]], %[[BB]] ]661; CHECK-NEXT:    ret i32 [[RES]]662;663bb:664  %entry = call token @llvm.experimental.convergence.entry()665  br i1 %cond, label %then, label %end666 667then:668  %val = add i32 %arg, 16777215669  %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %val) [ "convergencectrl"(token %entry)]670  br label %end671 672end:673  %res = phi i32 [%rfl, %then], [%arg, %bb]674  ret i32 %res675}676