forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			1265 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1265 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 | |
| // RUN: %clang_cc1 -triple armv8-none-linux-eabi %s -emit-llvm -o - -O3 | FileCheck %s -check-prefix=LE
 | |
| // RUN: %clang_cc1 -triple armebv8-none-linux-eabi %s -emit-llvm -o - -O3 | FileCheck %s -check-prefix=BE
 | |
| // RUN: %clang_cc1 -triple armv8-none-linux-eabi %s -emit-llvm -o - -O3 -fAAPCSBitfieldLoad | FileCheck %s -check-prefixes=LE,LENUMLOADS
 | |
| // RUN: %clang_cc1 -triple armebv8-none-linux-eabi %s -emit-llvm -o - -O3 -fAAPCSBitfieldLoad | FileCheck %s -check-prefixes=BE,BENUMLOADS
 | |
| 
 | |
| struct st0 {
 | |
|   short c : 7;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st0_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST0:%.*]], %struct.st0* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i8 [[BF_SHL]], 1
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st0_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST0:%.*]], %struct.st0* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st0_check_load(struct st0 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st0_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST0:%.*]], %struct.st0* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store i8 [[BF_SET]], i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st0_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST0:%.*]], %struct.st0* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2
 | |
| // BE-NEXT:    store i8 [[BF_SET]], i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st0_check_store(struct st0 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| 
 | |
| struct st1 {
 | |
|   int a : 10;
 | |
|   short c : 6;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st1_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST1:%.*]], %struct.st1* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 10
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st1_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST1:%.*]], %struct.st1* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 10
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i16 [[BF_SHL]], 10
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st1_check_load(struct st1 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st1_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST1:%.*]], %struct.st1* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], 1023
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 1024
 | |
| // LE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st1_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST1:%.*]], %struct.st1* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -64
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 1
 | |
| // BE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st1_check_store(struct st1 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| 
 | |
| struct st2 {
 | |
|   int a : 10;
 | |
|   short c : 7;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st2_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], %struct.st2* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[C]], align 2
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i8 [[BF_SHL]], 1
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st2_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], %struct.st2* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[C]], align 2
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st2_check_load(struct st2 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st2_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], %struct.st2* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[C]], align 2
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store i8 [[BF_SET]], i8* [[C]], align 2
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st2_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], %struct.st2* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i8, i8* [[C]], align 2
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2
 | |
| // BE-NEXT:    store i8 [[BF_SET]], i8* [[C]], align 2
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st2_check_store(struct st2 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| // Volatile access is allowed to use 16 bits
 | |
| struct st3 {
 | |
|   volatile short c : 7;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st3_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST3:%.*]], %struct.st3* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i8 [[BF_SHL]], 1
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st3_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST3:%.*]], %struct.st3* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st3_check_load(struct st3 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st3_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST3:%.*]], %struct.st3* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store volatile i8 [[BF_SET]], i8* [[TMP0]], align 2
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st3_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST3:%.*]], %struct.st3* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2
 | |
| // BE-NEXT:    store volatile i8 [[BF_SET]], i8* [[TMP0]], align 2
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st3_check_store(struct st3 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| // Volatile access to st4.c should use a char ld/st
 | |
| struct st4 {
 | |
|   int b : 9;
 | |
|   volatile char c : 5;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st4_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 2
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 11
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = zext i16 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    [[SEXT:%.*]] = shl i32 [[BF_CAST]], 24
 | |
| // LE-NEXT:    [[CONV:%.*]] = ashr exact i32 [[SEXT]], 24
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st4_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 9
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 11
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = zext i16 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    [[SEXT:%.*]] = shl i32 [[BF_CAST]], 24
 | |
| // BE-NEXT:    [[CONV:%.*]] = ashr exact i32 [[SEXT]], 24
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st4_check_load(struct st4 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st4_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -15873
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 512
 | |
| // LE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st4_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -125
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 4
 | |
| // BE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st4_check_store(struct st4 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st4_check_nonv_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -512
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st4_check_nonv_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST4:%.*]], %struct.st4* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], 127
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 128
 | |
| // BE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st4_check_nonv_store(struct st4 *m) {
 | |
|   m->b = 1;
 | |
| }
 | |
| 
 | |
| struct st5 {
 | |
|   int a : 12;
 | |
|   volatile char c : 5;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st5_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], %struct.st5* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[C]], align 2
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i8 [[BF_SHL]], 3
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| // BE-LABEL: @st5_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], %struct.st5* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[C]], align 2
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[CONV]]
 | |
| //
 | |
| int st5_check_load(struct st5 *m) {
 | |
|   return m->c;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st5_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], %struct.st5* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[C]], align 2
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store volatile i8 [[BF_SET]], i8* [[C]], align 2
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st5_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], %struct.st5* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[C]], align 2
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 8
 | |
| // BE-NEXT:    store volatile i8 [[BF_SET]], i8* [[C]], align 2
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st5_check_store(struct st5 *m) {
 | |
|   m->c = 1;
 | |
| }
 | |
| 
 | |
| struct st6 {
 | |
|   int a : 12;
 | |
|   char b;
 | |
|   int c : 5;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st6_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST6:%.*]], %struct.st6* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 4
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i16 [[BF_SHL]], 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = load volatile i8, i8* [[B]], align 2
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]]
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 2
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[C]], align 1
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = shl i8 [[BF_LOAD1]], 3
 | |
| // LE-NEXT:    [[BF_ASHR3:%.*]] = ashr exact i8 [[BF_SHL2]], 3
 | |
| // LE-NEXT:    [[BF_CAST4:%.*]] = sext i8 [[BF_ASHR3]] to i32
 | |
| // LE-NEXT:    [[ADD5:%.*]] = add nsw i32 [[ADD]], [[BF_CAST4]]
 | |
| // LE-NEXT:    ret i32 [[ADD5]]
 | |
| //
 | |
| // BE-LABEL: @st6_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST6:%.*]], %struct.st6* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 4
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 1
 | |
| // BE-NEXT:    [[TMP1:%.*]] = load volatile i8, i8* [[B]], align 2
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]]
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 2
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[C]], align 1
 | |
| // BE-NEXT:    [[BF_ASHR2:%.*]] = ashr i8 [[BF_LOAD1]], 3
 | |
| // BE-NEXT:    [[BF_CAST3:%.*]] = sext i8 [[BF_ASHR2]] to i32
 | |
| // BE-NEXT:    [[ADD4:%.*]] = add nsw i32 [[ADD]], [[BF_CAST3]]
 | |
| // BE-NEXT:    ret i32 [[ADD4]]
 | |
| //
 | |
| int st6_check_load(volatile struct st6 *m) {
 | |
|   int x = m->a;
 | |
|   x += m->b;
 | |
|   x += m->c;
 | |
|   return x;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st6_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST6:%.*]], %struct.st6* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -4096
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 1
 | |
| // LE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 1
 | |
| // LE-NEXT:    store i8 2, i8* [[B]], align 2
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 2
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load i8, i8* [[C]], align 1
 | |
| // LE-NEXT:    [[BF_CLEAR2:%.*]] = and i8 [[BF_LOAD1]], -32
 | |
| // LE-NEXT:    [[BF_SET3:%.*]] = or i8 [[BF_CLEAR2]], 3
 | |
| // LE-NEXT:    store i8 [[BF_SET3]], i8* [[C]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st6_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST6:%.*]], %struct.st6* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], 15
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 16
 | |
| // BE-NEXT:    store i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 1
 | |
| // BE-NEXT:    store i8 2, i8* [[B]], align 2
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], %struct.st6* [[M]], i32 0, i32 2
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load i8, i8* [[C]], align 1
 | |
| // BE-NEXT:    [[BF_CLEAR2:%.*]] = and i8 [[BF_LOAD1]], 7
 | |
| // BE-NEXT:    [[BF_SET3:%.*]] = or i8 [[BF_CLEAR2]], 24
 | |
| // BE-NEXT:    store i8 [[BF_SET3]], i8* [[C]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st6_check_store(struct st6 *m) {
 | |
|   m->a = 1;
 | |
|   m->b = 2;
 | |
|   m->c = 3;
 | |
| }
 | |
| 
 | |
| // Nested structs and bitfields.
 | |
| struct st7a {
 | |
|   char a;
 | |
|   int b : 5;
 | |
| };
 | |
| 
 | |
| struct st7b {
 | |
|   char x;
 | |
|   volatile struct st7a y;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st7_check_load(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_ST7B:%.*]], %struct.st7b* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[TMP0:%.*]] = load i8, i8* [[X]], align 4
 | |
| // LE-NEXT:    [[CONV:%.*]] = sext i8 [[TMP0]] to i32
 | |
| // LE-NEXT:    [[A:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 0
 | |
| // LE-NEXT:    [[TMP1:%.*]] = load volatile i8, i8* [[A]], align 4
 | |
| // LE-NEXT:    [[CONV1:%.*]] = sext i8 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
 | |
| // LE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[B]], align 1
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr exact i8 [[BF_SHL]], 3
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    [[ADD3:%.*]] = add nsw i32 [[ADD]], [[BF_CAST]]
 | |
| // LE-NEXT:    ret i32 [[ADD3]]
 | |
| //
 | |
| // BE-LABEL: @st7_check_load(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_ST7B:%.*]], %struct.st7b* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[TMP0:%.*]] = load i8, i8* [[X]], align 4
 | |
| // BE-NEXT:    [[CONV:%.*]] = sext i8 [[TMP0]] to i32
 | |
| // BE-NEXT:    [[A:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 0
 | |
| // BE-NEXT:    [[TMP1:%.*]] = load volatile i8, i8* [[A]], align 4
 | |
| // BE-NEXT:    [[CONV1:%.*]] = sext i8 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
 | |
| // BE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[B]], align 1
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    [[ADD3:%.*]] = add nsw i32 [[ADD]], [[BF_CAST]]
 | |
| // BE-NEXT:    ret i32 [[ADD3]]
 | |
| //
 | |
| int st7_check_load(struct st7b *m) {
 | |
|   int r = m->x;
 | |
|   r += m->y.a;
 | |
|   r += m->y.b;
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @st7_check_store(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_ST7B:%.*]], %struct.st7b* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    store i8 1, i8* [[X]], align 4
 | |
| // LE-NEXT:    [[A:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 0
 | |
| // LE-NEXT:    store volatile i8 2, i8* [[A]], align 4
 | |
| // LE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[B]], align 1
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 3
 | |
| // LE-NEXT:    store volatile i8 [[BF_SET]], i8* [[B]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @st7_check_store(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_ST7B:%.*]], %struct.st7b* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    store i8 1, i8* [[X]], align 4
 | |
| // BE-NEXT:    [[A:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 0
 | |
| // BE-NEXT:    store volatile i8 2, i8* [[A]], align 4
 | |
| // BE-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_ST7B]], %struct.st7b* [[M]], i32 0, i32 2, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[B]], align 1
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 24
 | |
| // BE-NEXT:    store volatile i8 [[BF_SET]], i8* [[B]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void st7_check_store(struct st7b *m) {
 | |
|   m->x = 1;
 | |
|   m->y.a = 2;
 | |
|   m->y.b = 3;
 | |
| }
 | |
| 
 | |
| // Check overflowing assignments to bitfields.
 | |
| struct st8 {
 | |
|   unsigned f : 16;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @st8_check_assignment(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST8:%.*]], %struct.st8* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    store i16 -1, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret i32 65535
 | |
| //
 | |
| // BE-LABEL: @st8_check_assignment(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST8:%.*]], %struct.st8* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    store i16 -1, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret i32 65535
 | |
| //
 | |
| int st8_check_assignment(struct st8 *m) {
 | |
|   return m->f = 0xffff;
 | |
| }
 | |
| 
 | |
| struct st9{
 | |
|   int f : 8;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @read_st9(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| // BE-LABEL: @read_st9(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| int read_st9(volatile struct st9 *m) {
 | |
|   return m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @store_st9(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    store volatile i8 1, i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @store_st9(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    store volatile i8 1, i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void store_st9(volatile struct st9 *m) {
 | |
|   m->f = 1;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_st9(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_st9(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST9:%.*]], %struct.st9* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_st9(volatile struct st9 *m) {
 | |
|   ++m->f;
 | |
| }
 | |
| 
 | |
| struct st10{
 | |
|   int e : 1;
 | |
|   int f : 8;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @read_st10(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 7
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // LE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| // BE-LABEL: @read_st10(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 1
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
 | |
| // BE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| int read_st10(volatile struct st10 *m) {
 | |
|   return m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @store_st10(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -511
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 2
 | |
| // LE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @store_st10(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -32641
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 128
 | |
| // BE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void store_st10(volatile struct st10 *m) {
 | |
|   m->f = 1;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_st10(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP1:%.*]] = add i16 [[BF_LOAD]], 2
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = and i16 [[TMP1]], 510
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -511
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // LE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_st10(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST10:%.*]], %struct.st10* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i16, i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = add i16 [[BF_LOAD]], 128
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = and i16 [[TMP1]], 32640
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -32641
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store volatile i16 [[BF_SET]], i16* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_st10(volatile struct st10 *m) {
 | |
|   ++m->f;
 | |
| }
 | |
| 
 | |
| struct st11{
 | |
|   char e;
 | |
|   int f : 16;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @read_st11(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| // BE-LABEL: @read_st11(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    ret i32 [[BF_CAST]]
 | |
| //
 | |
| int read_st11(volatile struct st11 *m) {
 | |
|   return m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @store_st11(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // LE-NEXT:    store volatile i16 1, i16* [[F]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @store_st11(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // BE-NEXT:    store volatile i16 1, i16* [[F]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void store_st11(volatile struct st11 *m) {
 | |
|   m->f = 1;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_st11(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // LE-NEXT:    [[INC:%.*]] = add i16 [[BF_LOAD]], 1
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // LE-NEXT:    store volatile i16 [[INC]], i16* [[F]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_st11(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // BE-NEXT:    [[INC:%.*]] = add i16 [[BF_LOAD]], 1
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i16, i16* [[F]], align 1
 | |
| // BE-NEXT:    store volatile i16 [[INC]], i16* [[F]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_st11(volatile struct st11 *m) {
 | |
|   ++m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_e_st11(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[E:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[TMP0:%.*]] = load volatile i8, i8* [[E]], align 4
 | |
| // LE-NEXT:    [[INC:%.*]] = add i8 [[TMP0]], 1
 | |
| // LE-NEXT:    store volatile i8 [[INC]], i8* [[E]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_e_st11(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[E:%.*]] = getelementptr inbounds [[STRUCT_ST11:%.*]], %struct.st11* [[M:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[TMP0:%.*]] = load volatile i8, i8* [[E]], align 4
 | |
| // BE-NEXT:    [[INC:%.*]] = add i8 [[TMP0]], 1
 | |
| // BE-NEXT:    store volatile i8 [[INC]], i8* [[E]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_e_st11(volatile struct st11 *m) {
 | |
|   ++m->e;
 | |
| }
 | |
| 
 | |
| struct st12{
 | |
|   int e : 8;
 | |
|   int f : 16;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @read_st12(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 8
 | |
| // LE-NEXT:    [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16
 | |
| // LE-NEXT:    ret i32 [[BF_ASHR]]
 | |
| //
 | |
| // BE-LABEL: @read_st12(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 8
 | |
| // BE-NEXT:    [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16
 | |
| // BE-NEXT:    ret i32 [[BF_ASHR]]
 | |
| //
 | |
| int read_st12(volatile struct st12 *m) {
 | |
|   return m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @store_st12(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -16776961
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 256
 | |
| // LE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @store_st12(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -16776961
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 256
 | |
| // BE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void store_st12(volatile struct st12 *m) {
 | |
|   m->f = 1;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_st12(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[INC3:%.*]] = add i32 [[BF_LOAD]], 256
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = and i32 [[INC3]], 16776960
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -16776961
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // LE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_st12(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[INC3:%.*]] = add i32 [[BF_LOAD]], 256
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = and i32 [[INC3]], 16776960
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -16776961
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_st12(volatile struct st12 *m) {
 | |
|   ++m->f;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_e_st12(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[INC:%.*]] = add i32 [[BF_LOAD]], 1
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_VALUE:%.*]] = and i32 [[INC]], 255
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -256
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_VALUE]]
 | |
| // LE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_e_st12(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st12* [[M:%.*]] to i32*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i32, i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = add i32 [[BF_LOAD]], 16777216
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = and i32 [[TMP1]], -16777216
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], 16777215
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL]]
 | |
| // BE-NEXT:    store volatile i32 [[BF_SET]], i32* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_e_st12(volatile struct st12 *m) {
 | |
|   ++m->e;
 | |
| }
 | |
| 
 | |
| struct st13 {
 | |
|   char a : 8;
 | |
|   int b : 32;
 | |
| } __attribute__((packed));
 | |
| 
 | |
| // LE-LABEL: @increment_b_st13(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st13* [[S:%.*]] to i40*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i40 [[BF_LOAD]], 8
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i40
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl nuw i40 [[TMP2]], 8
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_b_st13(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st13* [[S:%.*]] to i40*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i40
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[TMP1]]
 | |
| // BE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_b_st13(volatile struct st13 *s) {
 | |
|   s->b++;
 | |
| }
 | |
| 
 | |
| struct st14 {
 | |
|   char a : 8;
 | |
| } __attribute__((packed));
 | |
| 
 | |
| // LE-LABEL: @increment_a_st14(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST14:%.*]], %struct.st14* [[S:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_a_st14(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST14:%.*]], %struct.st14* [[S:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_a_st14(volatile struct st14 *s) {
 | |
|   s->a++;
 | |
| }
 | |
| 
 | |
| struct st15 {
 | |
|   short a : 8;
 | |
| } __attribute__((packed));
 | |
| 
 | |
| // LE-LABEL: @increment_a_st15(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST15:%.*]], %struct.st15* [[S:%.*]], i32 0, i32 0
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // LENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_a_st15(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_ST15:%.*]], %struct.st15* [[S:%.*]], i32 0, i32 0
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[INC:%.*]] = add i8 [[BF_LOAD]], 1
 | |
| // BENUMLOADS-NEXT:    [[BF_LOAD1:%.*]] = load volatile i8, i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    store volatile i8 [[INC]], i8* [[TMP0]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_a_st15(volatile struct st15 *s) {
 | |
|   s->a++;
 | |
| }
 | |
| 
 | |
| struct st16 {
 | |
|   int a : 32;
 | |
|   int b : 16;
 | |
|   int c : 32;
 | |
|   int d : 16;
 | |
| };
 | |
| 
 | |
| // LE-LABEL: @increment_a_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i64
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -4294967296
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[TMP1]]
 | |
| // LE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_a_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i64
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl nuw i64 [[TMP2]], 32
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], 4294967295
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // BE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_a_st16(struct st16 *s) {
 | |
|   s->a++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_b_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // LE-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add i32 [[TMP2]], 1
 | |
| // LE-NEXT:    [[TMP3:%.*]] = and i32 [[INC]], 65535
 | |
| // LE-NEXT:    [[BF_VALUE:%.*]] = zext i32 [[TMP3]] to i64
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = shl nuw nsw i64 [[BF_VALUE]], 32
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -281470681743361
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL2]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_b_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    [[INC4:%.*]] = add i32 [[TMP1]], 65536
 | |
| // BE-NEXT:    [[TMP2:%.*]] = and i32 [[INC4]], -65536
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = zext i32 [[TMP2]] to i64
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -4294901761
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_b_st16(struct st16 *s) {
 | |
|   s->b++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_c_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[C]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i64
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -4294967296
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[TMP1]]
 | |
| // LE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_c_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[C]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i64
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl nuw i64 [[TMP2]], 32
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], 4294967295
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // BE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_c_st16(struct st16 *s) {
 | |
|   s->c++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_d_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[D]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // LE-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add i32 [[TMP2]], 1
 | |
| // LE-NEXT:    [[TMP3:%.*]] = and i32 [[INC]], 65535
 | |
| // LE-NEXT:    [[BF_VALUE:%.*]] = zext i32 [[TMP3]] to i64
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = shl nuw nsw i64 [[BF_VALUE]], 32
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -281470681743361
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL2]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_d_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[D]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    [[INC4:%.*]] = add i32 [[TMP1]], 65536
 | |
| // BE-NEXT:    [[TMP2:%.*]] = and i32 [[INC4]], -65536
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = zext i32 [[TMP2]] to i64
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD]], -4294901761
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_d_st16(struct st16 *s) {
 | |
|   s->d++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_v_a_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i64
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[TMP1]]
 | |
| // LE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_a_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i64
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl nuw i64 [[TMP2]], 32
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // BE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_a_st16(volatile struct st16 *s) {
 | |
|   s->a++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_v_b_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // LE-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add i32 [[TMP2]], 1
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP3:%.*]] = and i32 [[INC]], 65535
 | |
| // LE-NEXT:    [[BF_VALUE:%.*]] = zext i32 [[TMP3]] to i64
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = shl nuw nsw i64 [[BF_VALUE]], 32
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL2]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_b_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st16* [[S:%.*]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    [[INC4:%.*]] = add i32 [[TMP1]], 65536
 | |
| // BE-NEXT:    [[TMP2:%.*]] = and i32 [[INC4]], -65536
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = zext i32 [[TMP2]] to i64
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_b_st16(volatile struct st16 *s) {
 | |
|   s->b++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_v_c_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[C]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i64
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[TMP1]]
 | |
| // LE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_c_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[C]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i64
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl nuw i64 [[TMP2]], 32
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // BE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_c_st16(volatile struct st16 *s) {
 | |
|   s->c++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_v_d_st16(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[D]] to i64*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i64 [[BF_LOAD]], 32
 | |
| // LE-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add i32 [[TMP2]], 1
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    [[TMP3:%.*]] = and i32 [[INC]], 65535
 | |
| // LE-NEXT:    [[BF_VALUE:%.*]] = zext i32 [[TMP3]] to i64
 | |
| // LE-NEXT:    [[BF_SHL2:%.*]] = shl nuw nsw i64 [[BF_VALUE]], 32
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_SHL2]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_d_st16(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], %struct.st16* [[S:%.*]], i32 0, i32 1
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast i48* [[D]] to i64*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i64, i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    [[TMP1:%.*]] = trunc i64 [[BF_LOAD]] to i32
 | |
| // BE-NEXT:    [[INC4:%.*]] = add i32 [[TMP1]], 65536
 | |
| // BE-NEXT:    [[TMP2:%.*]] = and i32 [[INC4]], -65536
 | |
| // BE-NEXT:    [[BF_SHL2:%.*]] = zext i32 [[TMP2]] to i64
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]]
 | |
| // BE-NEXT:    store volatile i64 [[BF_SET]], i64* [[TMP0]], align 4
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_d_st16(volatile struct st16 *s) {
 | |
|   s->d++;
 | |
| }
 | |
| // st17 has alignment = 1, the AAPCS defines nothing for the
 | |
| // accessing of b, but accessing c should use char
 | |
| struct st17 {
 | |
| int b : 32;
 | |
| char c : 8;
 | |
| } __attribute__((packed));
 | |
| 
 | |
| // LE-LABEL: @increment_v_b_st17(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st17* [[S:%.*]] to i40*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[BF_LOAD]] to i32
 | |
| // LE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = zext i32 [[INC]] to i40
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[TMP1]]
 | |
| // LE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_b_st17(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st17* [[S:%.*]] to i40*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[TMP1:%.*]] = lshr i40 [[BF_LOAD]], 8
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[TMP1]] to i32
 | |
| // BE-NEXT:    [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP2:%.*]] = zext i32 [[INC]] to i40
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[BF_SHL:%.*]] = shl nuw i40 [[TMP2]], 8
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // BE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_b_st17(volatile struct st17 *s) {
 | |
|   s->b++;
 | |
| }
 | |
| 
 | |
| // LE-LABEL: @increment_v_c_st17(
 | |
| // LE-NEXT:  entry:
 | |
| // LE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st17* [[S:%.*]] to i40*
 | |
| // LE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[TMP1:%.*]] = lshr i40 [[BF_LOAD]], 32
 | |
| // LE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[TMP1]] to i8
 | |
| // LE-NEXT:    [[INC:%.*]] = add i8 [[BF_CAST]], 1
 | |
| // LE-NEXT:    [[TMP2:%.*]] = zext i8 [[INC]] to i40
 | |
| // LE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    [[BF_SHL:%.*]] = shl nuw i40 [[TMP2]], 32
 | |
| // LE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 4294967295
 | |
| // LE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_SHL]], [[BF_CLEAR]]
 | |
| // LE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // LE-NEXT:    ret void
 | |
| //
 | |
| // BE-LABEL: @increment_v_c_st17(
 | |
| // BE-NEXT:  entry:
 | |
| // BE-NEXT:    [[TMP0:%.*]] = bitcast %struct.st17* [[S:%.*]] to i40*
 | |
| // BE-NEXT:    [[BF_LOAD:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[BF_CAST:%.*]] = trunc i40 [[BF_LOAD]] to i8
 | |
| // BE-NEXT:    [[INC:%.*]] = add i8 [[BF_CAST]], 1
 | |
| // BE-NEXT:    [[TMP1:%.*]] = zext i8 [[INC]] to i40
 | |
| // BE-NEXT:    [[BF_LOAD1:%.*]] = load volatile i40, i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -256
 | |
| // BE-NEXT:    [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[TMP1]]
 | |
| // BE-NEXT:    store volatile i40 [[BF_SET]], i40* [[TMP0]], align 1
 | |
| // BE-NEXT:    ret void
 | |
| //
 | |
| void increment_v_c_st17(volatile struct st17 *s) {
 | |
|   s->c++;
 | |
| }
 |