match(LHS, m_c_Xor(m_c_And(m_Specific(RHS), m_Value(Y)), m_Deferred(Y))))
return true;
- // Peek through extends:
+ // Peek through extends to find a 'not' of the other side:
// (ext Y) op ext(~Y)
- if (match(LHS, m_ZExtOrSExt(m_Value(Y))) &&
- match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y)))))
+ // (ext ~Y) op ext(Y)
+ if ((match(LHS, m_ZExtOrSExt(m_Value(Y))) &&
+ match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))) ||
+ (match(RHS, m_ZExtOrSExt(m_Value(Y))) &&
+ match(LHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))))
return true;
// Look for: (A & B) op ~(A | B)
define i5 @zext_zext_not(i3 %x) {
; CHECK-LABEL: @zext_zext_not(
-; CHECK-NEXT: [[ZX:%.*]] = zext i3 [[X:%.*]] to i5
-; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
-; CHECK-NEXT: [[ZNOTX:%.*]] = zext i3 [[NOTX]] to i5
-; CHECK-NEXT: [[R:%.*]] = add nuw nsw i5 [[ZX]], [[ZNOTX]]
-; CHECK-NEXT: ret i5 [[R]]
+; CHECK-NEXT: ret i5 7
;
%zx = zext i3 %x to i5
%notx = xor i3 %x, -1
define <2 x i5> @zext_zext_not_commute(<2 x i3> %x) {
; CHECK-LABEL: @zext_zext_not_commute(
-; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i3> [[X:%.*]] to <2 x i5>
-; CHECK-NEXT: [[NOTX:%.*]] = xor <2 x i3> [[X]], <i3 -1, i3 poison>
-; CHECK-NEXT: [[ZNOTX:%.*]] = zext <2 x i3> [[NOTX]] to <2 x i5>
-; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i5> [[ZNOTX]], [[ZX]]
-; CHECK-NEXT: ret <2 x i5> [[R]]
+; CHECK-NEXT: ret <2 x i5> <i5 7, i5 7>
;
%zx = zext <2 x i3> %x to <2 x i5>
%notx = xor <2 x i3> %x, <i3 -1, i3 poison>
define i9 @sext_sext_not(i3 %x) {
; CHECK-LABEL: @sext_sext_not(
-; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i9
-; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
-; CHECK-NEXT: [[SNOTX:%.*]] = sext i3 [[NOTX]] to i9
-; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[SX]], [[SNOTX]]
-; CHECK-NEXT: ret i9 [[R]]
+; CHECK-NEXT: ret i9 -1
;
%sx = sext i3 %x to i9
%notx = xor i3 %x, -1
; CHECK-LABEL: @sext_sext_not_commute(
; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[SX]])
-; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
-; CHECK-NEXT: [[SNOTX:%.*]] = sext i3 [[NOTX]] to i8
-; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SNOTX]], [[SX]]
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 -1
;
%sx = sext i3 %x to i8
call void @use(i8 %sx)
; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5
-; CHECK-NEXT: [[R:%.*]] = add i5 [[ZX]], [[SNOTX]]
+; CHECK-NEXT: [[R:%.*]] = or i5 [[ZX]], [[SNOTX]]
; CHECK-NEXT: ret i5 [[R]]
;
%zx = zext i4 %x to i5
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8
; CHECK-NEXT: call void @use(i8 [[SNOTX]])
-; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SNOTX]], [[ZX]]
+; CHECK-NEXT: [[R:%.*]] = or i8 [[SNOTX]], [[ZX]]
; CHECK-NEXT: ret i8 [[R]]
;
%zx = zext i4 %x to i8
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
-; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[SX]], [[ZNOTX]]
+; CHECK-NEXT: [[R:%.*]] = or i9 [[SX]], [[ZNOTX]]
; CHECK-NEXT: ret i9 [[R]]
;
%sx = sext i4 %x to i9
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
-; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[ZNOTX]], [[SX]]
+; CHECK-NEXT: [[R:%.*]] = or i9 [[ZNOTX]], [[SX]]
; CHECK-NEXT: ret i9 [[R]]
;
%sx = sext i4 %x to i9