mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	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
This commit is contained in:
		@@ -1520,6 +1520,15 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
 | 
				
			|||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// stripPointerAdjustments - This is like Value::stripPointerCasts, but also
 | 
				
			||||||
 | 
					/// removes inbounds gep operations, regardless of their indices.
 | 
				
			||||||
 | 
					static Value *stripPointerAdjustments(Value *V) {
 | 
				
			||||||
 | 
					  if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
 | 
				
			||||||
 | 
					    if (GEP->isInBounds())
 | 
				
			||||||
 | 
					      return stripPointerAdjustments(GEP->getOperand(0)->stripPointerCasts());
 | 
				
			||||||
 | 
					  return V;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
 | 
					/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
 | 
				
			||||||
/// fold the result.  If not, this returns null.
 | 
					/// fold the result.  If not, this returns null.
 | 
				
			||||||
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 | 
					static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 | 
				
			||||||
@@ -1595,10 +1604,18 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 | 
				
			|||||||
  Value *RHSPtr = RHS->stripPointerCasts();
 | 
					  Value *RHSPtr = RHS->stripPointerCasts();
 | 
				
			||||||
  if (LHSPtr == RHSPtr)
 | 
					  if (LHSPtr == RHSPtr)
 | 
				
			||||||
    return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
 | 
					    return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
 | 
				
			||||||
  if (isa<AllocaInst>(LHSPtr) && (isa<GlobalValue>(RHSPtr) ||
 | 
					  
 | 
				
			||||||
                                  isa<AllocaInst>(RHSPtr)  ||
 | 
					  // Be more aggressive about stripping pointer adjustments when checking a
 | 
				
			||||||
 | 
					  // comparison of an alloca address to another object.  We can rip off all
 | 
				
			||||||
 | 
					  // inbounds GEP operations, even if they are variable.
 | 
				
			||||||
 | 
					  LHSPtr = stripPointerAdjustments(LHSPtr);
 | 
				
			||||||
 | 
					  if (isa<AllocaInst>(LHSPtr)) {
 | 
				
			||||||
 | 
					    RHSPtr = stripPointerAdjustments(RHSPtr);
 | 
				
			||||||
 | 
					    if (LHSPtr != RHSPtr &&
 | 
				
			||||||
 | 
					        (isa<GlobalValue>(RHSPtr) || isa<AllocaInst>(RHSPtr)  ||
 | 
				
			||||||
         isa<ConstantPointerNull>(RHSPtr)))
 | 
					         isa<ConstantPointerNull>(RHSPtr)))
 | 
				
			||||||
      return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
 | 
					      return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // If we are comparing with zero then try hard since this is a common case.
 | 
					  // If we are comparing with zero then try hard since this is a common case.
 | 
				
			||||||
  if (match(RHS, m_Zero())) {
 | 
					  if (match(RHS, m_Zero())) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -446,9 +446,20 @@ define <2 x i1> @vectorselect1(<2 x i1> %cond) {
 | 
				
			|||||||
; CHECK: ret <2 x i1> %cond
 | 
					; CHECK: ret <2 x i1> %cond
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
define <2 x i1> @vectorselectcrash(i32 %arg1) { ; PR11948
 | 
					; PR11948
 | 
				
			||||||
 | 
					define <2 x i1> @vectorselectcrash(i32 %arg1) {
 | 
				
			||||||
  %tobool40 = icmp ne i32 %arg1, 0
 | 
					  %tobool40 = icmp ne i32 %arg1, 0
 | 
				
			||||||
  %cond43 = select i1 %tobool40, <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
 | 
					  %cond43 = select i1 %tobool40, <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
 | 
				
			||||||
  %cmp45 = icmp ugt <2 x i16> %cond43, <i16 73, i16 21>
 | 
					  %cmp45 = icmp ugt <2 x i16> %cond43, <i16 73, i16 21>
 | 
				
			||||||
  ret <2 x i1> %cmp45
 | 
					  ret <2 x i1> %cmp45
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; PR12013
 | 
				
			||||||
 | 
					define i1 @alloca_compare(i64 %idx) {
 | 
				
			||||||
 | 
					  %sv = alloca { i32, i32, [124 x i32] }
 | 
				
			||||||
 | 
					  %1 = getelementptr inbounds { i32, i32, [124 x i32] }* %sv, i32 0, i32 2, i64 %idx
 | 
				
			||||||
 | 
					  %2 = icmp eq i32* %1, null
 | 
				
			||||||
 | 
					  ret i1 %2
 | 
				
			||||||
 | 
					  ; CHECK: alloca_compare
 | 
				
			||||||
 | 
					  ; CHECK: ret i1 false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user