265 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -passes=newgvn -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}120 121define double @fcmp_une_not_zero(double %x, double %y) {122; CHECK-LABEL: define double @fcmp_une_not_zero(123; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {124; CHECK-NEXT: entry:125; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], 2.000000e+00126; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]127; CHECK: else:128; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00129; CHECK-NEXT: br label [[RETURN]]130; CHECK: return:131; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]132; CHECK-NEXT: ret double [[RETVAL]]133;134entry:135 %cmp = fcmp une double %y, 2.0136 br i1 %cmp, label %return, label %else137 138else:139 %div = fdiv double %x, %y140 br label %return141 142return:143 %retval = phi double [ %div, %else ], [ %x, %entry ]144 ret double %retval145 146}147 148; PR22376 - We can't propagate zero constants because -0.0149; compares equal to 0.0. If %y is -0.0 in this test case,150; we would produce the wrong sign on the infinity return value.151define double @fcmp_oeq_zero(double %x, double %y) {152; CHECK-LABEL: define double @fcmp_oeq_zero(153; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {154; CHECK-NEXT: entry:155; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00156; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]157; CHECK: if:158; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]159; CHECK-NEXT: br label [[RETURN]]160; CHECK: return:161; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], [[IF]] ], [ [[X]], [[ENTRY:%.*]] ]162; CHECK-NEXT: ret double [[RETVAL]]163;164entry:165 %cmp = fcmp oeq double %y, 0.0166 br i1 %cmp, label %if, label %return167 168if:169 %div = fdiv double %x, %y170 br label %return171 172return:173 %retval = phi double [ %div, %if ], [ %x, %entry ]174 ret double %retval175 176}177 178define double @fcmp_une_zero(double %x, double %y) {179; CHECK-LABEL: define double @fcmp_une_zero(180; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {181; CHECK-NEXT: entry:182; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], -0.000000e+00183; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]184; CHECK: else:185; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]186; CHECK-NEXT: br label [[RETURN]]187; CHECK: return:188; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]189; CHECK-NEXT: ret double [[RETVAL]]190;191entry:192 %cmp = fcmp une double %y, -0.0193 br i1 %cmp, label %return, label %else194 195else:196 %div = fdiv double %x, %y197 br label %return198 199return:200 %retval = phi double [ %div, %else ], [ %x, %entry ]201 ret double %retval202 203}204 205; We also cannot propagate a value if it's not a constant.206; This is because the value could be 0.0 or -0.0.207 208define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {209; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(210; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {211; CHECK-NEXT: entry:212; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]213; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], [[Z]]214; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]215; CHECK: if:216; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]217; CHECK-NEXT: br label [[RETURN]]218; CHECK: return:219; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], [[IF]] ], [ [[X]], [[ENTRY:%.*]] ]220; CHECK-NEXT: ret double [[RETVAL]]221;222entry:223 %z = fadd double %z1, %z2224 %cmp = fcmp oeq double %y, %z225 br i1 %cmp, label %if, label %return226 227if:228 %div = fdiv double %x, %z229 br label %return230 231return:232 %retval = phi double [ %div, %if ], [ %x, %entry ]233 ret double %retval234 235}236 237define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {238; CHECK-LABEL: define double @fcmp_une_maybe_zero(239; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {240; CHECK-NEXT: entry:241; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]242; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], [[Z]]243; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]244; CHECK: else:245; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]246; CHECK-NEXT: br label [[RETURN]]247; CHECK: return:248; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]249; CHECK-NEXT: ret double [[RETVAL]]250;251entry:252 %z = fadd double %z1, %z2253 %cmp = fcmp une double %y, %z254 br i1 %cmp, label %return, label %else255 256else:257 %div = fdiv double %x, %z258 br label %return259 260return:261 %retval = phi double [ %div, %else ], [ %x, %entry ]262 ret double %retval263 264}265