return BinaryOperator::CreateAnd(A, B);
}
+ // (sub (select (a, c, b)), (select (a, d, b))) -> (select (a, (sub c, d), 0))
+ // (sub (select (a, b, c)), (select (a, b, d))) -> (select (a, 0, (sub c, d)))
+ if (auto *SI0 = dyn_cast<SelectInst>(Op0)) {
+ if (auto *SI1 = dyn_cast<SelectInst>(Op1)) {
+ if (SI0->getCondition() == SI1->getCondition()) {
+ if (Value *V = SimplifySubInst(
+ SI0->getFalseValue(), SI1->getFalseValue(), I.hasNoSignedWrap(),
+ I.hasNoUnsignedWrap(), DL, TLI, DT, AC))
+ return SelectInst::Create(
+ SI0->getCondition(),
+ Builder->CreateSub(SI0->getTrueValue(), SI1->getTrueValue(), "",
+ /*HasNUW=*/I.hasNoUnsignedWrap(),
+ /*HasNSW=*/I.hasNoSignedWrap()),
+ V);
+ if (Value *V = SimplifySubInst(SI0->getTrueValue(), SI1->getTrueValue(),
+ I.hasNoSignedWrap(),
+ I.hasNoUnsignedWrap(), DL, TLI, DT, AC))
+ return SelectInst::Create(
+ SI0->getCondition(), V,
+ Builder->CreateSub(SI0->getFalseValue(), SI1->getFalseValue(), "",
+ /*HasNUW=*/I.hasNoUnsignedWrap(),
+ /*HasNSW=*/I.hasNoSignedWrap()));
+ }
+ }
+ }
+
if (Op0->hasOneUse()) {
Value *Y = nullptr;
// ((X | Y) - X) --> (~X & Y)
; CHECK-NEXT: %sub = and i32 %y, %x.not
; CHECK: ret i32 %sub
}
+
+define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) {
+ %sel0 = select i1 %A, i32 %D, i32 %B
+ %sel1 = select i1 %A, i32 %C, i32 %B
+ %sub = sub i32 %sel0, %sel1
+ ret i32 %sub
+; CHECK-LABEL: @test47(
+; CHECK-NEXT: %[[sub:.*]] = sub i32 %D, %C
+; CHECK-NEXT: %[[sel:.*]] = select i1 %A, i32 %[[sub]], i32 0
+; CHECK-NEXT: ret i32 %[[sel]]
+}
+
+define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) {
+ %sel0 = select i1 %A, i32 %B, i32 %D
+ %sel1 = select i1 %A, i32 %B, i32 %C
+ %sub = sub i32 %sel0, %sel1
+ ret i32 %sub
+; CHECK-LABEL: @test48(
+; CHECK-NEXT: %[[sub:.*]] = sub i32 %D, %C
+; CHECK-NEXT: %[[sel:.*]] = select i1 %A, i32 0, i32 %[[sub]]
+; CHECK-NEXT: ret i32 %[[sel]]
+}