}
}
- // (icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
- // iff -C is a power of 2
- if (Pred == ICmpInst::ICMP_UGT && *XorC == ~C && (C + 1).isPowerOf2())
- return new ICmpInst(ICmpInst::ICMP_ULT, X, Y);
-
- // (icmp ult (xor X, C), -C) -> (icmp uge X, C)
- // iff -C is a power of 2
- if (Pred == ICmpInst::ICMP_ULT && *XorC == -C && C.isPowerOf2())
- return new ICmpInst(ICmpInst::ICMP_UGE, X, Y);
-
+ // Mask constant magic can eliminate an 'xor' with unsigned compares.
+ if (Pred == ICmpInst::ICMP_UGT) {
+ // (xor X, ~C) >u C --> X <u ~C (when C+1 is a power of 2)
+ if (*XorC == ~C && (C + 1).isPowerOf2())
+ return new ICmpInst(ICmpInst::ICMP_ULT, X, Y);
+ // (xor X, C) >u C --> X >u C (when C+1 is a power of 2)
+ if (*XorC == C && (C + 1).isPowerOf2())
+ return new ICmpInst(ICmpInst::ICMP_UGT, X, Y);
+ }
+ if (Pred == ICmpInst::ICMP_ULT) {
+ // (xor X, -C) <u C --> X >u ~C (when C is a power of 2)
+ if (*XorC == -C && C.isPowerOf2())
+ return new ICmpInst(ICmpInst::ICMP_UGT, X,
+ ConstantInt::get(X->getType(), ~C));
+ // (xor X, C) <u C --> X >u ~C (when -C is a power of 2)
+ if (*XorC == C && (-C).isPowerOf2())
+ return new ICmpInst(ICmpInst::ICMP_UGT, X,
+ ConstantInt::get(X->getType(), ~C));
+ }
return nullptr;
}
define <2 x i1> @xor_ult(<2 x i8> %x) {
; CHECK-LABEL: @xor_ult(
-; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -4, i8 -4>
-; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[XOR]], <i8 -4, i8 -4>
+; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%xor = xor <2 x i8> %x, <i8 -4, i8 -4>
; CHECK-LABEL: @xor_ult_extra_use(
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32
; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
-; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[XOR]], -32
+; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, -32
; CHECK-LABEL: @xor_ugt_extra_use(
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63
; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
-; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[XOR]], 63
+; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, 63