llvm.org GIT mirror llvm / b053fc1
fold comparisons of gep'd alloca points with null to false, implementing PR12013. We now compile the testcase to: __Z4testv: ## @_Z4testv ## BB#0: ## %_ZN4llvm15SmallVectorImplIiE9push_backERKi.exit pushq %rbx subq $64, %rsp leaq 32(%rsp), %rbx movq %rbx, (%rsp) leaq 64(%rsp), %rax movq %rax, 16(%rsp) movl $1, 32(%rsp) leaq 36(%rsp), %rax movq %rax, 8(%rsp) leaq (%rsp), %rdi callq __Z1gRN4llvm11SmallVectorIiLj8EEE movq (%rsp), %rdi cmpq %rbx, %rdi je LBB0_2 ## BB#1: callq _free LBB0_2: ## %_ZN4llvm11SmallVectorIiLj8EED1Ev.exit addq $64, %rsp popq %rbx ret instead of: __Z4testv: ## @_Z4testv ## BB#0: pushq %rbx subq $64, %rsp xorl %eax, %eax leaq (%rsp), %rbx addq $32, %rbx movq %rbx, (%rsp) movq %rbx, 8(%rsp) leaq 64(%rsp), %rcx movq %rcx, 16(%rsp) je LBB0_2 ## BB#1: movl $1, 32(%rsp) movq %rbx, %rax LBB0_2: ## %_ZN4llvm15SmallVectorImplIiE9push_backERKi.exit addq $4, %rax movq %rax, 8(%rsp) leaq (%rsp), %rdi callq __Z1gRN4llvm11SmallVectorIiLj8EEE movq (%rsp), %rdi cmpq %rbx, %rdi je LBB0_4 ## BB#3: callq _free LBB0_4: ## %_ZN4llvm11SmallVectorIiLj8EED1Ev.exit addq $64, %rsp popq %rbx ret This doesn't shrink clang noticably though. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150944 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 7 years ago
2 changed file(s) with 33 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
15171517 LHS == CmpRHS && RHS == CmpLHS)
15181518 return Cmp;
15191519 return 0;
1520 }
1521
1522 /// stripPointerAdjustments - This is like Value::stripPointerCasts, but also
1523 /// removes inbounds gep operations, regardless of their indices.
1524 static Value *stripPointerAdjustments(Value *V) {
1525 if (GEPOperator *GEP = dyn_cast(V))
1526 if (GEP->isInBounds())
1527 return stripPointerAdjustments(GEP->getOperand(0)->stripPointerCasts());
1528 return V;
15201529 }
15211530
15221531 /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
15941603 Value *RHSPtr = RHS->stripPointerCasts();
15951604 if (LHSPtr == RHSPtr)
15961605 return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
1597 if (isa(LHSPtr) && (isa(RHSPtr) ||
1598 isa(RHSPtr) ||
1599 isa(RHSPtr)))
1600 return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
1606
1607 // Be more aggressive about stripping pointer adjustments when checking a
1608 // comparison of an alloca address to another object. We can rip off all
1609 // inbounds GEP operations, even if they are variable.
1610 LHSPtr = stripPointerAdjustments(LHSPtr);
1611 if (isa(LHSPtr)) {
1612 RHSPtr = stripPointerAdjustments(RHSPtr);
1613 if (LHSPtr != RHSPtr &&
1614 (isa(RHSPtr) || isa(RHSPtr) ||
1615 isa(RHSPtr)))
1616 return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
1617 }
16011618
16021619 // If we are comparing with zero then try hard since this is a common case.
16031620 if (match(RHS, m_Zero())) {
445445 ; CHECK: ret <2 x i1> %cond
446446 }
447447
448 define <2 x i1> @vectorselectcrash(i32 %arg1) { ; PR11948
448 ; PR11948
449 define <2 x i1> @vectorselectcrash(i32 %arg1) {
449450 %tobool40 = icmp ne i32 %arg1, 0
450451 %cond43 = select i1 %tobool40, <2 x i16> , <2 x i16>
451452 %cmp45 = icmp ugt <2 x i16> %cond43,
452453 ret <2 x i1> %cmp45
453454 }
455
456 ; PR12013
457 define i1 @alloca_compare(i64 %idx) {
458 %sv = alloca { i32, i32, [124 x i32] }
459 %1 = getelementptr inbounds { i32, i32, [124 x i32] }* %sv, i32 0, i32 2, i64 %idx
460 %2 = icmp eq i32* %1, null
461 ret i1 %2
462 ; CHECK: alloca_compare
463 ; CHECK: ret i1 false
464 }