219 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3 4define ptr @simplify_phi_common_value_op0(ptr %ptr, ptr %b) {5; CHECK-LABEL: @simplify_phi_common_value_op0(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null8; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]9; CHECK: else:10; CHECK-NEXT: [[LB:%.*]] = load i32, ptr [[B:%.*]], align 411; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LB]], 112; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 413; CHECK-NEXT: br label [[RETURN]]14; CHECK: return:15; CHECK-NEXT: ret ptr [[PTR]]16;17entry:18 %isnull = icmp eq ptr %ptr, null19 br i1 %isnull, label %return, label %else20 21else:22 %lb = load i32, ptr %b23 %add = add nsw i32 %lb, 124 store i32 %add, ptr %b25 br label %return26 27return:28 %r = phi ptr [ %ptr, %else ], [ null, %entry ]29 ret ptr %r30}31 32define ptr @simplify_phi_common_value_op1(ptr %ptr, ptr %b) {33; CHECK-LABEL: @simplify_phi_common_value_op1(34; CHECK-NEXT: entry:35; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null36; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]37; CHECK: else:38; CHECK-NEXT: [[LB:%.*]] = load i32, ptr [[B:%.*]], align 439; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LB]], 140; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 441; CHECK-NEXT: br label [[RETURN]]42; CHECK: return:43; CHECK-NEXT: ret ptr [[PTR]]44;45entry:46 %isnull = icmp eq ptr %ptr, null47 br i1 %isnull, label %return, label %else48 49else:50 %lb = load i32, ptr %b51 %add = add i32 %lb, 152 store i32 %add, ptr %b53 br label %return54 55return:56 %r = phi ptr [ null, %entry], [ %ptr, %else ]57 ret ptr %r58}59 60define i8 @simplify_phi_multiple_constants(i8 %x, ptr %b) {61; CHECK-LABEL: @simplify_phi_multiple_constants(62; CHECK-NEXT: entry:63; CHECK-NEXT: [[IS0:%.*]] = icmp eq i8 [[X:%.*]], 064; CHECK-NEXT: br i1 [[IS0]], label [[RETURN:%.*]], label [[ELSE1:%.*]]65; CHECK: else1:66; CHECK-NEXT: [[IS42:%.*]] = icmp eq i8 [[X]], 4267; CHECK-NEXT: br i1 [[IS42]], label [[RETURN]], label [[ELSE2:%.*]]68; CHECK: else2:69; CHECK-NEXT: [[LB:%.*]] = load i32, ptr [[B:%.*]], align 470; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LB]], 171; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 472; CHECK-NEXT: br label [[RETURN]]73; CHECK: return:74; CHECK-NEXT: ret i8 [[X]]75;76entry:77 %is0 = icmp eq i8 %x, 078 br i1 %is0, label %return, label %else179 80else1:81 %is42 = icmp eq i8 %x, 4282 br i1 %is42, label %return, label %else283 84else2:85 %lb = load i32, ptr %b86 %add = add i32 %lb, 187 store i32 %add, ptr %b88 br label %return89 90return:91 %r = phi i8 [ 0, %entry], [ %x, %else2 ], [ 42, %else1 ]92 ret i8 %r93}94 95define ptr @simplify_phi_common_value_from_instruction(ptr %ptr_op, ptr %b, i32 %i) {96; CHECK-LABEL: @simplify_phi_common_value_from_instruction(97; CHECK-NEXT: entry:98; CHECK-NEXT: [[PTR:%.*]] = getelementptr i8, ptr [[PTR_OP:%.*]], i32 [[I:%.*]]99; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[PTR]], null100; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]101; CHECK: else:102; CHECK-NEXT: [[LB:%.*]] = load i32, ptr [[B:%.*]], align 4103; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LB]], 1104; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 4105; CHECK-NEXT: br label [[RETURN]]106; CHECK: return:107; CHECK-NEXT: ret ptr [[PTR]]108;109entry:110 %ptr = getelementptr i8, ptr %ptr_op, i32 %i111 %isnull = icmp eq ptr %ptr, null112 br i1 %isnull, label %return, label %else113 114else:115 %lb = load i32, ptr %b116 %add = add nsw i32 %lb, 1117 store i32 %add, ptr %b118 br label %return119 120return:121 %r = phi ptr [ %ptr, %else ], [ null, %entry ]122 ret ptr %r123}124 125; The sub has 'nsw', so it is not safe to propagate that value along126; the bb2 edge because that would propagate poison to the return.127; FIXME: In this particular case, it would be possible to perform the128; transform if we drop nowrap flags from the sub.129 130define i32 @PR43802(i32 %arg) {131; CHECK-LABEL: @PR43802(132; CHECK-NEXT: entry:133; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[ARG:%.*]]134; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648135; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]]136; CHECK: bb2:137; CHECK-NEXT: br label [[BB3]]138; CHECK: bb3:139; CHECK-NEXT: [[R:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB]], [[ENTRY:%.*]] ]140; CHECK-NEXT: ret i32 [[R]]141;142entry:143 %sub = sub nsw i32 0, %arg144 %cmp = icmp eq i32 %arg, -2147483648145 br i1 %cmp, label %bb2, label %bb3146 147bb2:148 br label %bb3149 150bb3:151 %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]152 ret i32 %r153}154 155; Same as previous test case, but without nowrap flags.156define i32 @PR43802_without_nowrap(i32 %arg) {157; CHECK-LABEL: @PR43802_without_nowrap(158; CHECK-NEXT: entry:159; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 0, [[ARG:%.*]]160; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648161; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]]162; CHECK: bb2:163; CHECK-NEXT: br label [[BB3]]164; CHECK: bb3:165; CHECK-NEXT: [[SUB:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB1]], [[ENTRY:%.*]] ]166; CHECK-NEXT: ret i32 [[SUB]]167;168entry:169 %sub = sub i32 0, %arg170 %cmp = icmp eq i32 %arg, -2147483648171 br i1 %cmp, label %bb2, label %bb3172 173bb2:174 br label %bb3175 176bb3:177 %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]178 ret i32 %r179}180 181; Similar to the previous case, we know that %y is always poison on the182; entry -> join1 edge, and thus always zero or poison on the join1 -> join2183; edge. We need to make sure that we don't replace zero with "zero or poison".184 185define i8 @pr50399(i8 %x) {186; CHECK-LABEL: @pr50399(187; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -100188; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[X]], -100189; CHECK-NEXT: br i1 [[CMP]], label [[JOIN1:%.*]], label [[ELSE:%.*]]190; CHECK: else:191; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[Y]], 0192; CHECK-NEXT: br i1 [[CMP2]], label [[JOIN1]], label [[ELSE2:%.*]]193; CHECK: join1:194; CHECK-NEXT: br label [[JOIN2:%.*]]195; CHECK: else2:196; CHECK-NEXT: br label [[JOIN2]]197; CHECK: join2:198; CHECK-NEXT: [[PHI:%.*]] = phi i8 [ 0, [[JOIN1]] ], [ [[Y]], [[ELSE2]] ]199; CHECK-NEXT: ret i8 [[PHI]]200;201 %cmp = icmp slt i8 %x, -100202 %y = add nsw i8 %x, -100203 br i1 %cmp, label %join1, label %else204 205else: ; preds = %cond.end9206 %cmp2 = icmp eq i8 %y, 0207 br i1 %cmp2, label %join1, label %else2208 209join1:210 br label %join2211 212else2: ; preds = %bb213 br label %join2214 215join2:216 %phi = phi i8 [ 0, %join1 ], [ %y, %else2 ]217 ret i8 %phi218}219