mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	The C and C++ semantics for compare_exchange require it to return a bool
indicating success. This gets mapped to LLVM IR which follows each cmpxchg with
an icmp of the value loaded against the desired value.
When lowered to ldxr/stxr loops, this extra comparison is redundant: its
results are implicit in the control-flow of the function.
This commit makes two changes: it replaces that icmp with appropriate PHI
nodes, and then makes sure earlyCSE is called after expansion to actually make
use of the opportunities revealed.
I've also added -{arm,aarch64}-enable-atomic-tidy options, so that
existing fragile tests aren't perturbed too much by the change. Many
of them either rely on undef/unreachable too pervasively to be
restored to something well-defined (particularly while making sure
they test the same obscure assert from many years ago), or depend on a
particular CFG shape, which is disrupted by SimplifyCFG.
rdar://problem/16227836
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209883 91177308-0d34-0410-b5e6-96231b3b80d8
		
	
		
			
				
	
	
		
			65 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
| ; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 | FileCheck %s
 | |
| ; RUN: llc < %s -mtriple=thumbv7 -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
 | |
| ; CHECK: it	ne
 | |
| ; CHECK-NEXT: cmpne
 | |
| ; CHECK-NEXT: bne [[JUMPTARGET:.LBB[0-9]+_[0-9]+]]
 | |
| ; CHECK: cmp
 | |
| ; CHECK-NEXT: beq
 | |
| ; CHECK-NEXT: %if.else163
 | |
| ; CHECK-NEXT: mov.w
 | |
| ; CHECK-NEXT: b
 | |
| ; CHECK-NEXT: %if.else145
 | |
| ; CHECK-NEXT: mov.w
 | |
| ; CHECK: [[JUMPTARGET]]:{{.*}}%if.else173
 | |
| 
 | |
| %struct.hc = type { i32, i32, i32, i32 }
 | |
| 
 | |
| define i32 @t(i32 %type) optsize {
 | |
| entry:
 | |
|   br i1 undef, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   unreachable
 | |
| 
 | |
| if.else:
 | |
|   br i1 undef, label %if.then15, label %if.else18
 | |
| 
 | |
| if.then15:
 | |
|   unreachable
 | |
| 
 | |
| if.else18:
 | |
|   switch i32 %type, label %if.else173 [
 | |
|     i32 3, label %if.then115
 | |
|     i32 1, label %if.then102
 | |
|   ]
 | |
| 
 | |
| if.then102:
 | |
|   br i1 undef, label %cond.true10.i, label %t.exit
 | |
| 
 | |
| cond.true10.i:
 | |
|   br label %t.exit
 | |
| 
 | |
| t.exit:
 | |
|   unreachable
 | |
| 
 | |
| if.then115:
 | |
|   br i1 undef, label %if.else163, label %if.else145
 | |
| 
 | |
| if.else145:
 | |
|   %call150 = call fastcc %struct.hc* @foo(%struct.hc* undef, i32 34865152) optsize
 | |
|   br label %while.body172
 | |
| 
 | |
| if.else163:
 | |
|   %call168 = call fastcc %struct.hc* @foo(%struct.hc* undef, i32 34078720) optsize
 | |
|   br label %while.body172
 | |
| 
 | |
| while.body172:
 | |
|   br label %while.body172
 | |
| 
 | |
| if.else173:
 | |
|   ret i32 -1
 | |
| }
 | |
| 
 | |
| declare hidden fastcc %struct.hc* @foo(%struct.hc* nocapture, i32) nounwind optsize
 | |
| 
 |