InstCombinerImpl::BuilderTy &Builder) {
Instruction::BinaryOps Opcode = BO.getOpcode();
Value *X, *Y, *Z;
- if (match(&BO, m_c_BinOp(Opcode,
- m_OneUse(m_c_BinOp(Opcode, m_Value(X),
- m_OneUse(m_Value(Y)))),
- m_OneUse(m_Value(Z))))) {
- // (X op Y) op Z --> (Y op Z) op X
- if (!isa<Constant>(X) && !isa<Constant>(Y) && !isa<Constant>(Z) &&
- !X->hasOneUse()) {
- Value *YZ = Builder.CreateBinOp(Opcode, Y, Z);
- return BinaryOperator::Create(Opcode, YZ, X);
+ if (match(&BO,
+ m_c_BinOp(Opcode, m_OneUse(m_BinOp(Opcode, m_Value(X), m_Value(Y))),
+ m_OneUse(m_Value(Z))))) {
+ if (!isa<Constant>(X) && !isa<Constant>(Y) && !isa<Constant>(Z)) {
+ // (X op Y) op Z --> (Y op Z) op X
+ if (!X->hasOneUse()) {
+ Value *YZ = Builder.CreateBinOp(Opcode, Y, Z);
+ return BinaryOperator::Create(Opcode, YZ, X);
+ }
+ // (X op Y) op Z --> (X op Z) op Y
+ if (!Y->hasOneUse()) {
+ Value *XZ = Builder.CreateBinOp(Opcode, X, Z);
+ return BinaryOperator::Create(Opcode, XZ, Y);
+ }
}
}
define i4 @simplify_and_common_op_use1(i4 %x, i4 %y, i4 %z) {
; CHECK-LABEL: @simplify_and_common_op_use1(
-; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: call void @use(i4 [[Y]])
-; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
-; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
-; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
-; CHECK-NEXT: ret i4 [[R]]
+; CHECK-NEXT: call void @use(i4 [[Y:%.*]])
+; CHECK-NEXT: ret i4 0
;
%xy = or i4 %x, %y
call void @use(i4 %y)
define i4 @simplify_and_common_op_use2(i4 %x, i4 %y, i4 %z) {
; CHECK-LABEL: @simplify_and_common_op_use2(
+; CHECK-NEXT: call void @use(i4 [[Y:%.*]])
+; CHECK-NEXT: [[TMP1:%.*]] = or i4 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[TMP1]], [[Y]]
+; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
+; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
+; CHECK-NEXT: ret i4 [[R]]
+;
+ %xy = or i4 %y, %x
+ call void @use(i4 %y)
+ %xyz = or i4 %xy, %z
+ %not_xyz = xor i4 %xyz, -1
+ %r = and i4 %not_xyz, %x
+ ret i4 %r
+}
+
+; TODO: This should simplify.
+
+define i4 @simplify_and_common_op_use3(i4 %x, i4 %y, i4 %z) {
+; CHECK-LABEL: @simplify_and_common_op_use3(
; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
; CHECK-NEXT: call void @use(i4 [[Z]])