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