1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i32 @xor_domcondition(i32 %x, i32 %y) { 5; CHECK-LABEL: @xor_domcondition( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 8; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 9; CHECK: cond.true: 10; CHECK-NEXT: br label [[COND_END]] 11; CHECK: cond.end: 12; CHECK-NEXT: ret i32 0 13; 14entry: 15 %cmp = icmp eq i32 %x, %y 16 br i1 %cmp, label %cond.true, label %cond.end 17 18cond.true: 19 %xor = xor i32 %x, %y 20 br label %cond.end 21 22cond.end: 23 %cond = phi i32 [ %xor, %cond.true ], [ 0, %entry ] 24 ret i32 %cond 25} 26 27define i32 @sub_domcondition(i32 %x, i32 %y) { 28; CHECK-LABEL: @sub_domcondition( 29; CHECK-NEXT: entry: 30; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 31; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 32; CHECK: cond.true: 33; CHECK-NEXT: br label [[COND_END]] 34; CHECK: cond.end: 35; CHECK-NEXT: ret i32 0 36; 37entry: 38 %cmp = icmp eq i32 %x, %y 39 br i1 %cmp, label %cond.true, label %cond.end 40 41cond.true: 42 %sub = sub i32 %x, %y 43 br label %cond.end 44 45cond.end: 46 %cond = phi i32 [ %sub, %cond.true ], [ 0, %entry ] 47 ret i32 %cond 48} 49 50define i32 @udiv_domcondition(i32 %x, i32 %y) { 51; CHECK-LABEL: @udiv_domcondition( 52; CHECK-NEXT: entry: 53; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 54; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 55; CHECK: cond.true: 56; CHECK-NEXT: br label [[COND_END]] 57; CHECK: cond.end: 58; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 59; CHECK-NEXT: ret i32 [[COND]] 60; 61entry: 62 %cmp = icmp eq i32 %x, %y 63 br i1 %cmp, label %cond.true, label %cond.end 64 65cond.true: 66 %udiv = udiv i32 %x, %y 67 br label %cond.end 68 69cond.end: 70 %cond = phi i32 [ %udiv, %cond.true ], [ 0, %entry ] 71 ret i32 %cond 72} 73 74define i32 @sdiv_domcondition(i32 %x, i32 %y) { 75; CHECK-LABEL: @sdiv_domcondition( 76; CHECK-NEXT: entry: 77; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 78; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 79; CHECK: cond.true: 80; CHECK-NEXT: br label [[COND_END]] 81; CHECK: cond.end: 82; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 83; CHECK-NEXT: ret i32 [[COND]] 84; 85entry: 86 %cmp = icmp eq i32 %x, %y 87 br i1 %cmp, label %cond.true, label %cond.end 88 89cond.true: 90 %sdiv = sdiv i32 %x, %y 91 br label %cond.end 92 93cond.end: 94 %cond = phi i32 [ %sdiv, %cond.true ], [ 0, %entry ] 95 ret i32 %cond 96} 97 98define i32 @urem_domcondition(i32 %x, i32 %y) { 99; CHECK-LABEL: @urem_domcondition( 100; CHECK-NEXT: entry: 101; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 102; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 103; CHECK: cond.true: 104; CHECK-NEXT: br label [[COND_END]] 105; CHECK: cond.end: 106; CHECK-NEXT: ret i32 0 107; 108entry: 109 %cmp = icmp eq i32 %x, %y 110 br i1 %cmp, label %cond.true, label %cond.end 111 112cond.true: 113 %urem = urem i32 %x, %y 114 br label %cond.end 115 116cond.end: 117 %cond = phi i32 [ %urem, %cond.true ], [ 0, %entry ] 118 ret i32 %cond 119} 120 121define i32 @srem_domcondition(i32 %x, i32 %y) { 122; CHECK-LABEL: @srem_domcondition( 123; CHECK-NEXT: entry: 124; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 125; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 126; CHECK: cond.true: 127; CHECK-NEXT: br label [[COND_END]] 128; CHECK: cond.end: 129; CHECK-NEXT: ret i32 0 130; 131entry: 132 %cmp = icmp eq i32 %x, %y 133 br i1 %cmp, label %cond.true, label %cond.end 134 135cond.true: 136 %srem = srem i32 %x, %y 137 br label %cond.end 138 139cond.end: 140 %cond = phi i32 [ %srem, %cond.true ], [ 0, %entry ] 141 ret i32 %cond 142} 143 144; TODO: %and can be one of %x, %y 145define i32 @and_domcondition(i32 %x, i32 %y) { 146; CHECK-LABEL: @and_domcondition( 147; CHECK-NEXT: entry: 148; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 149; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 150; CHECK: cond.true: 151; CHECK-NEXT: br label [[COND_END]] 152; CHECK: cond.end: 153; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[Y]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 154; CHECK-NEXT: ret i32 [[COND]] 155; 156entry: 157 %cmp = icmp eq i32 %x, %y 158 br i1 %cmp, label %cond.true, label %cond.end 159 160cond.true: 161 %and = and i32 %x, %y 162 br label %cond.end 163 164cond.end: 165 %cond = phi i32 [ %and, %cond.true ], [ 0, %entry ] 166 ret i32 %cond 167} 168 169; TODO: %or can be one of %x, %y 170define i32 @or_domcondition(i32 %x, i32 %y) { 171; CHECK-LABEL: @or_domcondition( 172; CHECK-NEXT: entry: 173; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 174; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 175; CHECK: cond.true: 176; CHECK-NEXT: br label [[COND_END]] 177; CHECK: cond.end: 178; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[Y]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 179; CHECK-NEXT: ret i32 [[COND]] 180; 181entry: 182 %cmp = icmp eq i32 %x, %y 183 br i1 %cmp, label %cond.true, label %cond.end 184 185cond.true: 186 %or = or i32 %x, %y 187 br label %cond.end 188 189cond.end: 190 %cond = phi i32 [ %or, %cond.true ], [ 0, %entry ] 191 ret i32 %cond 192} 193 194; negative test, dominate condtion is not eq 195define i32 @xor_domcondition_negative(i32 %x, i32 %y) { 196; CHECK-LABEL: @xor_domcondition_negative( 197; CHECK-NEXT: entry: 198; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 199; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 200; CHECK: cond.true: 201; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 202; CHECK-NEXT: br label [[COND_END]] 203; CHECK: cond.end: 204; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[XOR]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 205; CHECK-NEXT: ret i32 [[COND]] 206; 207entry: 208 %cmp = icmp uge i32 %x, %y 209 br i1 %cmp, label %cond.true, label %cond.end 210 211cond.true: 212 %xor = xor i32 %x, %y 213 br label %cond.end 214 215cond.end: 216 %cond = phi i32 [ %xor, %cond.true ], [ 0, %entry ] 217 ret i32 %cond 218} 219 220define i32 @xor_simplify_by_dci(i32 %x, i32 %y, i1 %c) { 221; CHECK-LABEL: @xor_simplify_by_dci( 222; CHECK-NEXT: entry: 223; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 224; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 225; CHECK: cond.true: 226; CHECK-NEXT: br i1 [[C:%.*]], label [[XORBB:%.*]], label [[COND_END]] 227; CHECK: xorbb: 228; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 229; CHECK-NEXT: br label [[COND_END]] 230; CHECK: cond.end: 231; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[XOR]], [[XORBB]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[COND_TRUE]] ] 232; CHECK-NEXT: ret i32 [[COND]] 233; 234entry: 235 %cmp = icmp eq i32 %x, %y 236 br i1 %cmp, label %cond.true, label %cond.end 237 238cond.true: 239 br i1 %c, label %xorbb, label %cond.end 240 241xorbb: 242 %xor = xor i32 %x, %y 243 br label %cond.end 244 245cond.end: 246 %cond = phi i32 [ %xor, %xorbb ], [ 0, %entry ], [0, %cond.true] 247 ret i32 %cond 248} 249 250define void @icmp_simplify_by_dci(i32 %a, i32 %b, i1 %x) { 251; CHECK-LABEL: @icmp_simplify_by_dci( 252; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 253; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 254; CHECK: taken: 255; CHECK-NEXT: br i1 [[X:%.*]], label [[SELBB:%.*]], label [[END]] 256; CHECK: selbb: 257; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 258; CHECK-NEXT: [[C:%.*]] = select i1 [[CMP2]], i32 20, i32 0 259; CHECK-NEXT: call void @foo(i32 [[C]]) 260; CHECK-NEXT: br label [[END]] 261; CHECK: end: 262; CHECK-NEXT: ret void 263; 264 %cmp1 = icmp eq i32 %a, %b 265 br i1 %cmp1, label %end, label %taken 266 267taken: 268 br i1 %x, label %selbb, label %end 269 270selbb: 271 %cmp2 = icmp ne i32 %a, %b 272 %c = select i1 %cmp2, i32 20, i32 0 273 call void @foo(i32 %c) 274 br label %end 275 276end: 277 ret void 278} 279 280declare void @foo(i32) 281