175 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; RUN: llc -mtriple=thumbv7m -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-NODSP
 | |
| ; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-NODSP
 | |
| ; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false -arm-enable-scalar-dsp=true -mcpu=cortex-m33 %s -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-DSP
 | |
| ; RUN: llc -mtriple=thumbv7em %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -arm-enable-scalar-dsp-imms=true -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-DSP-IMM
 | |
| 
 | |
| ; Test that ARMCodeGenPrepare can handle:
 | |
| ; - loops
 | |
| ; - call operands
 | |
| ; - call return values
 | |
| ; - ret instructions
 | |
| ; We use nuw on the arithmetic instructions to avoid complications.
 | |
| 
 | |
| ; Check that the arguments are extended but then nothing else is.
 | |
| ; This also ensures that the pass can handle loops.
 | |
| ; CHECK-COMMON-LABEL: phi_feeding_phi_args
 | |
| ; CHECK-COMMON: uxtb
 | |
| ; CHECK-COMMON: uxtb
 | |
| ; CHECK-NOT: uxtb
 | |
| define void @phi_feeding_phi_args(i8 %a, i8 %b) {
 | |
| entry:
 | |
|   %0 = icmp ugt i8 %a, %b
 | |
|   br i1 %0, label %preheader, label %empty
 | |
| 
 | |
| empty:
 | |
|   br label %preheader
 | |
| 
 | |
| preheader:
 | |
|   %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
 | |
|   br label %loop
 | |
| 
 | |
| loop:
 | |
|   %val = phi i8 [ %1, %preheader ], [ %inc2, %if.end ]
 | |
|   %cmp = icmp ult i8 %val, 254
 | |
|   br i1 %cmp, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   %inc = sub nuw i8 %val, 2
 | |
|   br label %if.end
 | |
| 
 | |
| if.else:
 | |
|   %inc1 = shl nuw i8 %val, 1
 | |
|   br label %if.end
 | |
| 
 | |
| if.end:
 | |
|   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
 | |
|   %cmp1 = icmp eq i8 %inc2, 255
 | |
|   br i1 %cmp1, label %exit, label %loop
 | |
| 
 | |
| exit:
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; Same as above, but as the args are zeroext, we shouldn't see any uxts.
 | |
| ; CHECK-COMMON-LABEL: phi_feeding_phi_zeroext_args
 | |
| ; CHECK-COMMON-NOT: uxt
 | |
| define void @phi_feeding_phi_zeroext_args(i8 zeroext %a, i8 zeroext %b) {
 | |
| entry:
 | |
|   %0 = icmp ugt i8 %a, %b
 | |
|   br i1 %0, label %preheader, label %empty
 | |
| 
 | |
| empty:
 | |
|   br label %preheader
 | |
| 
 | |
| preheader:
 | |
|   %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
 | |
|   br label %loop
 | |
| 
 | |
| loop:
 | |
|   %val = phi i8 [ %1, %preheader ], [ %inc2, %if.end ]
 | |
|   %cmp = icmp ult i8 %val, 254
 | |
|   br i1 %cmp, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   %inc = sub nuw i8 %val, 2
 | |
|   br label %if.end
 | |
| 
 | |
| if.else:
 | |
|   %inc1 = shl nuw i8 %val, 1
 | |
|   br label %if.end
 | |
| 
 | |
| if.end:
 | |
|   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
 | |
|   %cmp1 = icmp eq i8 %inc2, 255
 | |
|   br i1 %cmp1, label %exit, label %loop
 | |
| 
 | |
| exit:
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; Just check that phis also work with i16s.
 | |
| ; CHECK-COMMON-LABEL: phi_i16:
 | |
| ; CHECK-COMMON-NOT:   uxt
 | |
| define void @phi_i16() {
 | |
| entry:
 | |
|   br label %loop
 | |
| 
 | |
| loop:
 | |
|   %val = phi i16 [ 0, %entry ], [ %inc2, %if.end ]
 | |
|   %cmp = icmp ult i16 %val, 128
 | |
|   br i1 %cmp, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   %inc = add nuw i16 %val, 2
 | |
|   br label %if.end
 | |
| 
 | |
| if.else:
 | |
|   %inc1 = add nuw i16 %val, 1
 | |
|   br label %if.end
 | |
| 
 | |
| if.end:
 | |
|   %inc2 = phi i16 [ %inc, %if.then], [ %inc1, %if.else ]
 | |
|   %cmp1 = icmp ult i16 %inc2, 253
 | |
|   br i1 %cmp1, label %loop, label %exit
 | |
| 
 | |
| exit:
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; CHECK-COMMON-LABEL: ret_i8
 | |
| ; CHECK-COMMON-NOT:   uxt
 | |
| define i8 @ret_i8() {
 | |
| entry:
 | |
|   br label %loop
 | |
| 
 | |
| loop:
 | |
|   %val = phi i8 [ 0, %entry ], [ %inc2, %if.end ]
 | |
|   %cmp = icmp ult i8 %val, 128
 | |
|   br i1 %cmp, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   %inc = add nuw i8 %val, 2
 | |
|   br label %if.end
 | |
| 
 | |
| if.else:
 | |
|   %inc1 = add nuw i8 %val, 1
 | |
|   br label %if.end
 | |
| 
 | |
| if.end:
 | |
|   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
 | |
|   %cmp1 = icmp ult i8 %inc2, 253
 | |
|   br i1 %cmp1, label %exit, label %loop
 | |
| 
 | |
| exit:
 | |
|   ret i8 %inc2
 | |
| }
 | |
| 
 | |
| ; CHECK-COMMON-LABEL: phi_multiple_undefs
 | |
| ; CHECK-COMMON-NOT:   uxt
 | |
| define i16 @phi_multiple_undefs(i16 zeroext %arg) {
 | |
| entry:
 | |
|   br label %loop
 | |
| 
 | |
| loop:
 | |
|   %val = phi i16 [ undef, %entry ], [ %inc2, %if.end ]
 | |
|   %cmp = icmp ult i16 %val, 128
 | |
|   br i1 %cmp, label %if.then, label %if.else
 | |
| 
 | |
| if.then:
 | |
|   %inc = add nuw i16 %val, 2
 | |
|   br label %if.end
 | |
| 
 | |
| if.else:
 | |
|   %inc1 = add nuw i16 %val, 1
 | |
|   br label %if.end
 | |
| 
 | |
| if.end:
 | |
|   %inc2 = phi i16 [ %inc, %if.then], [ %inc1, %if.else ]
 | |
|   %unrelated = phi i16 [ undef, %if.then ], [ %arg, %if.else ]
 | |
|   %cmp1 = icmp ult i16 %inc2, 253
 | |
|   br i1 %cmp1, label %loop, label %exit
 | |
| 
 | |
| exit:
 | |
|   ret i16 %unrelated
 | |
| }
 |