forked from OSchip/llvm-project
[InstCombine] Remove invariant group intrinsincs when comparing against null
We cannot leak any equivalency information by comparing against null since null never has virtual metadata associated with it (when null is not a valid dereferenceable pointer). Instcombine seems to make sure that a null will be on the RHS, so we don't have to check both operands. This fixes a missed optimization in llvm-test-suite's MultiSource lambda benchmark under -fstrict-vtable-pointers. Reviewed By: Prazek Differential Revision: https://reviews.llvm.org/D108734
This commit is contained in:
parent
4b1fde8a2b
commit
099e4bcd5d
|
@ -5702,6 +5702,23 @@ static Instruction *foldICmpOfUAddOv(ICmpInst &I) {
|
|||
return ExtractValueInst::Create(UAddOv, 1);
|
||||
}
|
||||
|
||||
static Instruction *foldICmpInvariantGroup(ICmpInst &I) {
|
||||
if (!I.getOperand(0)->getType()->isPointerTy() ||
|
||||
NullPointerIsDefined(
|
||||
I.getParent()->getParent(),
|
||||
I.getOperand(0)->getType()->getPointerAddressSpace())) {
|
||||
return nullptr;
|
||||
}
|
||||
Instruction *Op;
|
||||
if (match(I.getOperand(0), m_Instruction(Op)) &&
|
||||
match(I.getOperand(1), m_Zero()) &&
|
||||
Op->isLaunderOrStripInvariantGroup()) {
|
||||
return ICmpInst::Create(Instruction::ICmp, I.getPredicate(),
|
||||
Op->getOperand(0), I.getOperand(1));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
|
||||
bool Changed = false;
|
||||
const SimplifyQuery Q = SQ.getWithInstruction(&I);
|
||||
|
@ -5942,6 +5959,9 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
|
|||
if (Instruction *Res = foldVectorCmp(I, Builder))
|
||||
return Res;
|
||||
|
||||
if (Instruction *Res = foldICmpInvariantGroup(I))
|
||||
return Res;
|
||||
|
||||
return Changed ? &I : nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,8 +161,7 @@ define i16 addrspace(42)* @skipWithDifferentTypesDifferentAddrspace(i8* %a) {
|
|||
|
||||
define i1 @icmp_null_launder(i8* %a) {
|
||||
; CHECK-LABEL: @icmp_null_launder(
|
||||
; CHECK-NEXT: [[A2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[A:%.*]])
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A2]], null
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A:%.*]], null
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
|
||||
|
@ -172,8 +171,7 @@ define i1 @icmp_null_launder(i8* %a) {
|
|||
|
||||
define i1 @icmp_null_strip(i8* %a) {
|
||||
; CHECK-LABEL: @icmp_null_strip(
|
||||
; CHECK-NEXT: [[A2:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[A:%.*]])
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A2]], null
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A:%.*]], null
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%a2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
|
||||
|
@ -206,8 +204,7 @@ define i1 @icmp_null_strip_valid_null(i8* %a) #0 {
|
|||
; Check that null always becomes the RHS
|
||||
define i1 @icmp_null_launder_lhs(i8* %a) {
|
||||
; CHECK-LABEL: @icmp_null_launder_lhs(
|
||||
; CHECK-NEXT: [[A2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[A:%.*]])
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A2]], null
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A:%.*]], null
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
|
||||
|
@ -217,9 +214,7 @@ define i1 @icmp_null_launder_lhs(i8* %a) {
|
|||
|
||||
define i1 @icmp_null_launder_bitcasts(i32* %a) {
|
||||
; CHECK-LABEL: @icmp_null_launder_bitcasts(
|
||||
; CHECK-NEXT: [[A2:%.*]] = bitcast i32* [[A:%.*]] to i8*
|
||||
; CHECK-NEXT: [[A3:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[A2]])
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A3]], null
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i32* [[A:%.*]], null
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%a2 = bitcast i32* %a to i8*
|
||||
|
|
Loading…
Reference in New Issue