392 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes=gvn -S < %s | FileCheck %s3 4define i32 @f1(i32 %x) {5; CHECK-LABEL: define i32 @f1(6; CHECK-SAME: i32 [[X:%.*]]) {7; CHECK-NEXT: [[BB0:.*:]]8; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 09; CHECK-NEXT: br i1 [[CMP]], label %[[BB2:.*]], label %[[BB1:.*]]10; CHECK: [[BB1]]:11; CHECK-NEXT: br label %[[BB2]]12; CHECK: [[BB2]]:13; CHECK-NEXT: ret i32 [[X]]14;15bb0:16 %cmp = icmp eq i32 %x, 017 br i1 %cmp, label %bb2, label %bb118bb1:19 br label %bb220bb2:21 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]22 %foo = add i32 %cond, %x23 ret i32 %foo24}25 26define i32 @f2(i32 %x) {27; CHECK-LABEL: define i32 @f2(28; CHECK-SAME: i32 [[X:%.*]]) {29; CHECK-NEXT: [[BB0:.*:]]30; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X]], 031; CHECK-NEXT: br i1 [[CMP]], label %[[BB1:.*]], label %[[BB2:.*]]32; CHECK: [[BB1]]:33; CHECK-NEXT: br label %[[BB2]]34; CHECK: [[BB2]]:35; CHECK-NEXT: ret i32 [[X]]36;37bb0:38 %cmp = icmp ne i32 %x, 039 br i1 %cmp, label %bb1, label %bb240bb1:41 br label %bb242bb2:43 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]44 %foo = add i32 %cond, %x45 ret i32 %foo46}47 48define i32 @f3(i32 %x) {49; CHECK-LABEL: define i32 @f3(50; CHECK-SAME: i32 [[X:%.*]]) {51; CHECK-NEXT: [[BB0:.*:]]52; CHECK-NEXT: switch i32 [[X]], label %[[BB1:.*]] [53; CHECK-NEXT: i32 0, label %[[BB2:.*]]54; CHECK-NEXT: ]55; CHECK: [[BB1]]:56; CHECK-NEXT: br label %[[BB2]]57; CHECK: [[BB2]]:58; CHECK-NEXT: ret i32 [[X]]59;60bb0:61 switch i32 %x, label %bb1 [ i32 0, label %bb2]62bb1:63 br label %bb264bb2:65 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]66 %foo = add i32 %cond, %x67 ret i32 %foo68}69 70declare void @g(i1)71define void @f4(ptr %x) {72; CHECK-LABEL: define void @f4(73; CHECK-SAME: ptr [[X:%.*]]) {74; CHECK-NEXT: [[BB0:.*:]]75; CHECK-NEXT: [[Y:%.*]] = icmp eq ptr null, [[X]]76; CHECK-NEXT: br i1 [[Y]], label %[[BB2:.*]], label %[[BB1:.*]]77; CHECK: [[BB1]]:78; CHECK-NEXT: br label %[[BB2]]79; CHECK: [[BB2]]:80; CHECK-NEXT: call void @g(i1 [[Y]])81; CHECK-NEXT: ret void82;83bb0:84 %y = icmp eq ptr null, %x85 br i1 %y, label %bb2, label %bb186bb1:87 br label %bb288bb2:89 %zed = icmp eq ptr null, %x90 call void @g(i1 %zed)91 ret void92}93 94define double @fcmp_oeq_not_zero(double %x, double %y) {95; CHECK-LABEL: define double @fcmp_oeq_not_zero(96; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {97; CHECK-NEXT: [[ENTRY:.*]]:98; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 2.000000e+0099; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]100; CHECK: [[IF]]:101; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00102; CHECK-NEXT: br label %[[RETURN]]103; CHECK: [[RETURN]]:104; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]105; CHECK-NEXT: ret double [[RETVAL]]106;107entry:108 %cmp = fcmp oeq double %y, 2.0109 br i1 %cmp, label %if, label %return110 111if:112 %div = fdiv double %x, %y113 br label %return114 115return:116 %retval = phi double [ %div, %if ], [ %x, %entry ]117 ret double %retval118}119 120define double @fcmp_une_not_zero(double %x, double %y) {121; CHECK-LABEL: define double @fcmp_une_not_zero(122; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {123; CHECK-NEXT: [[ENTRY:.*]]:124; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], 2.000000e+00125; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]126; CHECK: [[ELSE]]:127; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00128; CHECK-NEXT: br label %[[RETURN]]129; CHECK: [[RETURN]]:130; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]131; CHECK-NEXT: ret double [[RETVAL]]132;133entry:134 %cmp = fcmp une double %y, 2.0135 br i1 %cmp, label %return, label %else136 137else:138 %div = fdiv double %x, %y139 br label %return140 141return:142 %retval = phi double [ %div, %else ], [ %x, %entry ]143 ret double %retval144}145 146define double @fcmp_one_possibly_nan(double %x, double %y) {147; CHECK-LABEL: define double @fcmp_one_possibly_nan(148; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {149; CHECK-NEXT: [[ENTRY:.*]]:150; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[Y]], 2.000000e+00151; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]152; CHECK: [[ELSE]]:153; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]154; CHECK-NEXT: br label %[[RETURN]]155; CHECK: [[RETURN]]:156; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]157; CHECK-NEXT: ret double [[RETVAL]]158;159entry:160 %cmp = fcmp one double %y, 2.0161 br i1 %cmp, label %return, label %else162 163else:164 %div = fdiv double %x, %y165 br label %return166 167return:168 %retval = phi double [ %div, %else ], [ %x, %entry ]169 ret double %retval170}171 172define double @fcmp_one_not_zero_or_nan(double %x, double %y) {173; CHECK-LABEL: define double @fcmp_one_not_zero_or_nan(174; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {175; CHECK-NEXT: [[ENTRY:.*]]:176; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one double [[Y]], 2.000000e+00177; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]178; CHECK: [[ELSE]]:179; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00180; CHECK-NEXT: br label %[[RETURN]]181; CHECK: [[RETURN]]:182; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]183; CHECK-NEXT: ret double [[RETVAL]]184;185entry:186 %cmp = fcmp nnan one double %y, 2.0187 br i1 %cmp, label %return, label %else188 189else:190 %div = fdiv double %x, %y191 br label %return192 193return:194 %retval = phi double [ %div, %else ], [ %x, %entry ]195 ret double %retval196}197 198; PR22376 - We can't propagate zero constants because -0.0199; compares equal to 0.0. If %y is -0.0 in this test case,200; we would produce the wrong sign on the infinity return value.201define double @fcmp_oeq_zero(double %x, double %y) {202; CHECK-LABEL: define double @fcmp_oeq_zero(203; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {204; CHECK-NEXT: [[ENTRY:.*]]:205; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00206; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]207; CHECK: [[IF]]:208; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]209; CHECK-NEXT: br label %[[RETURN]]210; CHECK: [[RETURN]]:211; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]212; CHECK-NEXT: ret double [[RETVAL]]213;214entry:215 %cmp = fcmp oeq double %y, 0.0216 br i1 %cmp, label %if, label %return217 218if:219 %div = fdiv double %x, %y220 br label %return221 222return:223 %retval = phi double [ %div, %if ], [ %x, %entry ]224 ret double %retval225}226 227; Denormals may be flushed to zero in some cases by the backend.228; Hence, treat denormals as 0.229define float @fcmp_oeq_denormal(float %x, float %y) {230; CHECK-LABEL: define float @fcmp_oeq_denormal(231; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {232; CHECK-NEXT: [[ENTRY:.*]]:233; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[Y]], 0x3800000000000000234; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]235; CHECK: [[IF]]:236; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X]], [[Y]]237; CHECK-NEXT: br label %[[RETURN]]238; CHECK: [[RETURN]]:239; CHECK-NEXT: [[RETVAL:%.*]] = phi float [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]240; CHECK-NEXT: ret float [[RETVAL]]241;242entry:243 %cmp = fcmp oeq float %y, 0x3800000000000000244 br i1 %cmp, label %if, label %return245 246if:247 %div = fdiv float %x, %y248 br label %return249 250return:251 %retval = phi float [ %div, %if ], [ %x, %entry ]252 ret float %retval253}254 255define double @fcmp_une_zero(double %x, double %y) {256; CHECK-LABEL: define double @fcmp_une_zero(257; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {258; CHECK-NEXT: [[ENTRY:.*]]:259; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], -0.000000e+00260; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]261; CHECK: [[ELSE]]:262; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]263; CHECK-NEXT: br label %[[RETURN]]264; CHECK: [[RETURN]]:265; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]266; CHECK-NEXT: ret double [[RETVAL]]267;268entry:269 %cmp = fcmp une double %y, -0.0270 br i1 %cmp, label %return, label %else271 272else:273 %div = fdiv double %x, %y274 br label %return275 276return:277 %retval = phi double [ %div, %else ], [ %x, %entry ]278 ret double %retval279}280 281; We also cannot propagate a value if it's not a constant.282; This is because the value could be 0.0, -0.0, or a denormal.283 284define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {285; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(286; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {287; CHECK-NEXT: [[ENTRY:.*]]:288; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]289; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], [[Z]]290; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]291; CHECK: [[IF]]:292; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]293; CHECK-NEXT: br label %[[RETURN]]294; CHECK: [[RETURN]]:295; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]296; CHECK-NEXT: ret double [[RETVAL]]297;298entry:299 %z = fadd double %z1, %z2300 %cmp = fcmp oeq double %y, %z301 br i1 %cmp, label %if, label %return302 303if:304 %div = fdiv double %x, %z305 br label %return306 307return:308 %retval = phi double [ %div, %if ], [ %x, %entry ]309 ret double %retval310}311 312define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {313; CHECK-LABEL: define double @fcmp_une_maybe_zero(314; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {315; CHECK-NEXT: [[ENTRY:.*]]:316; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]317; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], [[Z]]318; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]319; CHECK: [[ELSE]]:320; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]321; CHECK-NEXT: br label %[[RETURN]]322; CHECK: [[RETURN]]:323; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]324; CHECK-NEXT: ret double [[RETVAL]]325;326entry:327 %z = fadd double %z1, %z2328 %cmp = fcmp une double %y, %z329 br i1 %cmp, label %return, label %else330 331else:332 %div = fdiv double %x, %z333 br label %return334 335return:336 %retval = phi double [ %div, %else ], [ %x, %entry ]337 ret double %retval338}339 340 341define double @fcmp_ueq_possibly_nan(double %x, double %y) {342; CHECK-LABEL: define double @fcmp_ueq_possibly_nan(343; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {344; CHECK-NEXT: [[ENTRY:.*]]:345; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[Y]], 2.000000e+00346; CHECK-NEXT: br i1 [[CMP]], label %[[DO_DIV:.*]], label %[[RETURN:.*]]347; CHECK: [[DO_DIV]]:348; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]349; CHECK-NEXT: br label %[[RETURN]]350; CHECK: [[RETURN]]:351; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[DO_DIV]] ], [ [[X]], %[[ENTRY]] ]352; CHECK-NEXT: ret double [[RETVAL]]353;354entry:355 %cmp = fcmp ueq double %y, 2.0356 br i1 %cmp, label %do_div, label %return357 358do_div:359 %div = fdiv double %x, %y360 br label %return361 362return:363 %retval = phi double [ %div, %do_div ], [ %x, %entry ]364 ret double %retval365}366 367define double @fcmp_ueq_not_zero_or_nan(double %x, double %y) {368; CHECK-LABEL: define double @fcmp_ueq_not_zero_or_nan(369; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {370; CHECK-NEXT: [[ENTRY:.*]]:371; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq double [[Y]], 2.000000e+00372; CHECK-NEXT: br i1 [[CMP]], label %[[DO_DIV:.*]], label %[[RETURN:.*]]373; CHECK: [[DO_DIV]]:374; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00375; CHECK-NEXT: br label %[[RETURN]]376; CHECK: [[RETURN]]:377; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[DO_DIV]] ], [ [[X]], %[[ENTRY]] ]378; CHECK-NEXT: ret double [[RETVAL]]379;380entry:381 %cmp = fcmp nnan ueq double %y, 2.0382 br i1 %cmp, label %do_div, label %return383 384do_div:385 %div = fdiv double %x, %y386 br label %return387 388return:389 %retval = phi double [ %div, %do_div ], [ %x, %entry ]390 ret double %retval391}392