15230dbe8faa9d5d291b07b9def438e56ed416009Rafael Espindola// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
2ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth// RUN:   | FileCheck -check-prefix=CHECK-X86-64 %s
35230dbe8faa9d5d291b07b9def438e56ed416009Rafael Espindola// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm -o - %s \
4ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth// RUN:   | FileCheck -check-prefix=CHECK-PPC64 %s
572d2dab6058467036df73a5f668036a519043e5bChandler Carruth//
672d2dab6058467036df73a5f668036a519043e5bChandler Carruth// Tests for bitfield access patterns in C++ with special attention to
772d2dab6058467036df73a5f668036a519043e5bChandler Carruth// conformance to C++11 memory model requirements.
872d2dab6058467036df73a5f668036a519043e5bChandler Carruth
95588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruthnamespace N0 {
105588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  // Test basic bitfield layout access across interesting byte and word
115588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  // boundaries on both little endian and big endian platforms.
125588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  struct __attribute__((packed)) S {
135588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b00 : 14;
145588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b01 : 2;
155588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b20 : 6;
165588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b21 : 2;
175588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b30 : 30;
185588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b31 : 2;
195588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b70 : 6;
205588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    unsigned b71 : 2;
215588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  };
225588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read00(S* s) {
2393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read00
245588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
265588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[val]], 16383
275588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
285588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
2993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read00
305588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
325588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 50
335588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[shr]] to i32
345588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
355588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b00;
365588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
375588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read01(S* s) {
3893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read01
395588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
415588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 14
425588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 3
435588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
445588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
4593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read01
465588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
485588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 48
495588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 3
505588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
515588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
525588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b01;
535588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
545588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read20(S* s) {
5593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read20
565588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
585588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 16
595588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 63
605588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
615588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
6293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read20
635588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
655588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 42
665588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 63
675588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
685588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
695588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b20;
705588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
715588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read21(S* s) {
7293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read21
735588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
755588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 22
765588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 3
775588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
785588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
7993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read21
805588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
825588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 40
835588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 3
845588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
855588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
865588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b21;
875588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
885588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read30(S* s) {
8993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read30
905588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
925588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 24
935588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 1073741823
945588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
955588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
9693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read30
975588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
995588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 10
1005588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 1073741823
1015588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1025588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
1035588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b30;
1045588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
1055588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read31(S* s) {
10693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read31
1075588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1095588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 54
1105588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 3
1115588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1125588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
11393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read31
1145588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1165588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 8
1175588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 3
1185588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1195588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
1205588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b31;
1215588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
1225588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read70(S* s) {
12393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read70
1245588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1265588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 56
1275588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[and:.*]]   = and i64 %[[shr]], 63
1285588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1295588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
13093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read70
1315588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1335588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]]   = lshr i64 %[[val]], 2
1345588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[shr]], 63
1355588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1365588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
1375588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b70;
1385588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
1395588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  unsigned read71(S* s) {
14093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N06read71
1415588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1435588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[shr:.*]]   = lshr i64 %[[val]], 62
1445588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:   %[[trunc:.*]] = trunc i64 %[[shr]] to i32
1455588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-X86-64:                   ret i32 %[[trunc]]
14693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read71
1475588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]   = bitcast %{{.*}}* %{{.*}} to i64*
1483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]]   = load i64, i64* %[[ptr]]
1495588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[and:.*]]   = and i64 %[[val]], 3
1505588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:   %[[trunc:.*]] = trunc i64 %[[and]] to i32
1515588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    // CHECK-PPC64:                   ret i32 %[[trunc]]
1525588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth    return s->b71;
1535588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth  }
1545588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth}
1555588a6903eb644e51c5e9b77939de16c61894fa8Chandler Carruth
15672d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N1 {
15772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Ensure that neither loads nor stores to bitfields are not widened into
15872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // other memory locations. (PR13691)
15972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  //
16072d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // NOTE: We could potentially widen loads based on their alignment if we are
16172d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // comfortable requiring that subsequent memory locations within the
16272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // alignment-widened load are not volatile.
16372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct S {
16472d2dab6058467036df73a5f668036a519043e5bChandler Carruth    char a;
16572d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned b : 1;
16672d2dab6058467036df73a5f668036a519043e5bChandler Carruth    char c;
16772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
16872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(S* s) {
16993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N14read
1703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
1713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i8, i8* %[[ptr]]
172ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[and:.*]] = and i8 %[[val]], 1
173ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ext:.*]] = zext i8 %[[and]] to i32
174ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 ret i32 %[[ext]]
17593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N14read
1763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
1773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i8, i8* %[[ptr]]
178ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]] = lshr i8 %[[val]], 7
179ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ext:.*]] = zext i8 %[[shr]] to i32
180ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 ret i32 %[[ext]]
18172d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return s->b;
18272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
18372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(S* s, unsigned x) {
18493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N15write
1853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[ptr:.*]]     = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
186ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8
1873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[old:.*]]     = load i8, i8* %[[ptr]]
188ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[x_and:.*]]   = and i8 %[[x_trunc]], 1
189ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[old_and:.*]] = and i8 %[[old]], -2
190ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new:.*]]     = or i8 %[[old_and]], %[[x_and]]
191ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                     store i8 %[[new]], i8* %[[ptr]]
19293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N15write
1933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[ptr:.*]]     = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
194ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8
1953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[old:.*]]     = load i8, i8* %[[ptr]]
196ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_and:.*]]   = and i8 %[[x_trunc]], 1
197ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_shl:.*]]   = shl i8 %[[x_and]], 7
198ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[old_and:.*]] = and i8 %[[old]], 127
199ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new:.*]]     = or i8 %[[old_and]], %[[x_shl]]
200ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                     store i8 %[[new]], i8* %[[ptr]]
20172d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b = x;
20272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
20372d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
20472d2dab6058467036df73a5f668036a519043e5bChandler Carruth
20572d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N2 {
20672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Do widen loads and stores to bitfields when those bitfields have padding
20772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // within the struct following them.
20872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct S {
20972d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned b : 24;
21072d2dab6058467036df73a5f668036a519043e5bChandler Carruth    void *p;
21172d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
21272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(S* s) {
21393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N24read
214ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
2153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i32, i32* %[[ptr]]
216ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[and:.*]] = and i32 %[[val]], 16777215
217ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 ret i32 %[[and]]
21893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N24read
219ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
2203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i32, i32* %[[ptr]]
221ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]] = lshr i32 %[[val]], 8
222ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 ret i32 %[[shr]]
22372d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return s->b;
22472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
22572d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(S* s, unsigned x) {
22693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N25write
227ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
2283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
229ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
230ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[old_and:.*]] = and i32 %[[old]], -16777216
231ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_and]]
232ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                     store i32 %[[new]], i32* %[[ptr]]
23393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N25write
234ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
2353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
236ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
237ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_shl:.*]]   = shl i32 %[[x_and]], 8
238ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[old_and:.*]] = and i32 %[[old]], 255
239ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_shl]]
240ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                     store i32 %[[new]], i32* %[[ptr]]
24172d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b = x;
24272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
24372d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
24472d2dab6058467036df73a5f668036a519043e5bChandler Carruth
24572d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N3 {
24672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Do widen loads and stores to bitfields through the trailing padding at the
24772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // end of a struct.
24872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct S {
24972d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned b : 24;
25072d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
25172d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(S* s) {
25293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N34read
253ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
2543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i32, i32* %[[ptr]]
255ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[and:.*]] = and i32 %[[val]], 16777215
256ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 ret i32 %[[and]]
25793ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N34read
258ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
2593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i32, i32* %[[ptr]]
260ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]] = lshr i32 %[[val]], 8
261ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 ret i32 %[[shr]]
26272d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return s->b;
26372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
26472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(S* s, unsigned x) {
26593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N35write
266ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
2673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
268ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
269ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[old_and:.*]] = and i32 %[[old]], -16777216
270ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_and]]
271ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                     store i32 %[[new]], i32* %[[ptr]]
27293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N35write
273ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
2743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
275ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
276ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_shl:.*]]   = shl i32 %[[x_and]], 8
277ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[old_and:.*]] = and i32 %[[old]], 255
278ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_shl]]
279ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                     store i32 %[[new]], i32* %[[ptr]]
28072d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b = x;
28172d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
28272d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
28372d2dab6058467036df73a5f668036a519043e5bChandler Carruth
28472d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N4 {
28572d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Do NOT widen loads and stores to bitfields into padding at the end of
28672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // a class which might end up with members inside of it when inside a derived
28772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // class.
28872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct Base {
28972d2dab6058467036df73a5f668036a519043e5bChandler Carruth    virtual ~Base() {}
29072d2dab6058467036df73a5f668036a519043e5bChandler Carruth
29172d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned b : 24;
29272d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
29372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Imagine some other translation unit introduces:
29472d2dab6058467036df73a5f668036a519043e5bChandler Carruth#if 0
29572d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct Derived : public Base {
29672d2dab6058467036df73a5f668036a519043e5bChandler Carruth    char c;
29772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
29872d2dab6058467036df73a5f668036a519043e5bChandler Carruth#endif
29972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(Base* s) {
30072d2dab6058467036df73a5f668036a519043e5bChandler Carruth    // FIXME: We should widen this load as long as the function isn't being
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // instrumented by ThreadSanitizer.
30272d2dab6058467036df73a5f668036a519043e5bChandler Carruth    //
30393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N44read
3043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
305ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
3063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i24, i24* %[[ptr]]
307ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ext:.*]] = zext i24 %[[val]] to i32
308ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 ret i32 %[[ext]]
30993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N44read
3103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
311ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
3123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i24, i24* %[[ptr]]
313ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ext:.*]] = zext i24 %[[val]] to i32
314ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 ret i32 %[[ext]]
31572d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return s->b;
31672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
31772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(Base* s, unsigned x) {
31893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N45write
3193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
320ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
321ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
322ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 store i24 %[[new]], i24* %[[ptr]]
32393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N45write
3243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
325ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
326ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
327ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 store i24 %[[new]], i24* %[[ptr]]
32872d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b = x;
32972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
33072d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
33172d2dab6058467036df73a5f668036a519043e5bChandler Carruth
33272d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N5 {
33372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Widen through padding at the end of a struct even if that struct
33472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // participates in a union with another struct which has a separate field in
33572d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // that location. The reasoning is that if the operation is storing to that
33672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // member of the union, it must be the active member, and thus we can write
33772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // through the padding. If it is a load, it might be a load of a common
33872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // prefix through a non-active member, but in such a case the extra bits
33972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // loaded are masked off anyways.
34072d2dab6058467036df73a5f668036a519043e5bChandler Carruth  union U {
34172d2dab6058467036df73a5f668036a519043e5bChandler Carruth    struct X { unsigned b : 24; char c; } x;
34272d2dab6058467036df73a5f668036a519043e5bChandler Carruth    struct Y { unsigned b : 24; } y;
34372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
34472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(U* u) {
34593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N54read
346ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
3473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i32, i32* %[[ptr]]
348ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[and:.*]] = and i32 %[[val]], 16777215
349ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                 ret i32 %[[and]]
35093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N54read
351ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
3523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i32, i32* %[[ptr]]
353ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[shr:.*]] = lshr i32 %[[val]], 8
354ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                 ret i32 %[[shr]]
35572d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return u->y.b;
35672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
35772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(U* u, unsigned x) {
35893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N55write
359ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
3603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
361ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
362ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[old_and:.*]] = and i32 %[[old]], -16777216
363ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_and]]
364ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                     store i32 %[[new]], i32* %[[ptr]]
36593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N55write
366ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr:.*]]     = bitcast %{{.*}}* %{{.*}} to i32*
3673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[old:.*]]     = load i32, i32* %[[ptr]]
368ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_and:.*]]   = and i32 %{{.*}}, 16777215
369ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[x_shl:.*]]   = shl i32 %[[x_and]], 8
370ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[old_and:.*]] = and i32 %[[old]], 255
371ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new:.*]]     = or i32 %[[old_and]], %[[x_shl]]
372ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                     store i32 %[[new]], i32* %[[ptr]]
37372d2dab6058467036df73a5f668036a519043e5bChandler Carruth    u->y.b = x;
37472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
37572d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
37672d2dab6058467036df73a5f668036a519043e5bChandler Carruth
37772d2dab6058467036df73a5f668036a519043e5bChandler Carruthnamespace N6 {
37872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // Zero-length bitfields partition the memory locations of bitfields for the
37972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // purposes of the memory model. That means stores must not span zero-length
38072d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // bitfields and loads may only span them when we are not instrumenting with
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // ThreadSanitizer.
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // FIXME: We currently don't widen loads even without ThreadSanitizer, even
38372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  // though we could.
38472d2dab6058467036df73a5f668036a519043e5bChandler Carruth  struct S {
38572d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned b1 : 24;
38672d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned char : 0;
38772d2dab6058467036df73a5f668036a519043e5bChandler Carruth    unsigned char b2 : 8;
38872d2dab6058467036df73a5f668036a519043e5bChandler Carruth  };
38972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  unsigned read(S* s) {
39093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define i32 @_ZN2N64read
391ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
3923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val1:.*]] = load i24, i24* %[[ptr1]]
393ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ext1:.*]] = zext i24 %[[val1]] to i32
3943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
3953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val2:.*]] = load i8, i8* %[[ptr2]]
396ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ext2:.*]] = zext i8 %[[val2]] to i32
397ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[add:.*]]  = add nsw i32 %[[ext1]], %[[ext2]]
398ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                  ret i32 %[[add]]
39993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N64read
400ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
4013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val1:.*]] = load i24, i24* %[[ptr1]]
402ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ext1:.*]] = zext i24 %[[val1]] to i32
4033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
4043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val2:.*]] = load i8, i8* %[[ptr2]]
405ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ext2:.*]] = zext i8 %[[val2]] to i32
406ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[add:.*]]  = add nsw i32 %[[ext1]], %[[ext2]]
407ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                  ret i32 %[[add]]
40872d2dab6058467036df73a5f668036a519043e5bChandler Carruth    return s->b1 + s->b2;
40972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
41072d2dab6058467036df73a5f668036a519043e5bChandler Carruth  void write(S* s, unsigned x) {
41193ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-X86-64-LABEL: define void @_ZN2N65write
412ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
413ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new1:.*]] = trunc i32 %{{.*}} to i24
414ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                  store i24 %[[new1]], i24* %[[ptr1]]
415ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:   %[[new2:.*]] = trunc i32 %{{.*}} to i8
4163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
417ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-X86-64:                  store i8 %[[new2]], i8* %[[ptr2]]
41893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    // CHECK-PPC64-LABEL: define void @_ZN2N65write
419ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
420ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new1:.*]] = trunc i32 %{{.*}} to i24
421ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                  store i24 %[[new1]], i24* %[[ptr1]]
422ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:   %[[new2:.*]] = trunc i32 %{{.*}} to i8
4233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
424ef8d516e7e015a905ca72ce99590803ca7c7e8f3Chandler Carruth    // CHECK-PPC64:                  store i8 %[[new2]], i8* %[[ptr2]]
42572d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b1 = x;
42672d2dab6058467036df73a5f668036a519043e5bChandler Carruth    s->b2 = x;
42772d2dab6058467036df73a5f668036a519043e5bChandler Carruth  }
42872d2dab6058467036df73a5f668036a519043e5bChandler Carruth}
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace N7 {
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Similar to N4 except that this adds a virtual base to the picture. (PR18430)
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Do NOT widen loads and stores to bitfields into padding at the end of
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // a class which might end up with members inside of it when inside a derived
434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // class.
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct B1 {
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    virtual void f();
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned b1 : 24;
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct B2 : virtual B1 {
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    virtual ~B2();
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned b : 24;
442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Imagine some other translation unit introduces:
444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if 0
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct Derived : public B2 {
446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    char c;
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned read(B2* s) {
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // FIXME: We should widen this load as long as the function isn't being
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // instrumented by ThreadSanitizer.
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64-LABEL: define i32 @_ZN2N74read
4543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
4563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[val:.*]] = load i24, i24* %[[ptr]]
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:   %[[ext:.*]] = zext i24 %[[val]] to i32
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:                 ret i32 %[[ext]]
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N74read
4603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
4623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[val:.*]] = load i24, i24* %[[ptr]]
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:   %[[ext:.*]] = zext i24 %[[val]] to i32
464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:                 ret i32 %[[ext]]
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return s->b;
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void write(B2* s, unsigned x) {
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64-LABEL: define void @_ZN2N75write
4693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-X86-64:                 store i24 %[[new]], i24* %[[ptr]]
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64-LABEL: define void @_ZN2N75write
4743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-PPC64:                 store i24 %[[new]], i24* %[[ptr]]
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    s->b = x;
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
481