@@ -2825,20 +2825,76 @@ struct PaddingClearer {
28252825 return Results;
28262826 }
28272827
2828- void ClearPadding (Value *Ptr, const BitInterval &PaddingInteval) {
2829- // TODO: support clearning non-one-byte clearing
2830- auto *I8Ptr = CGF.Builder .CreateBitCast (Ptr, CGF.Int8PtrTy );
2831- auto *Zero = ConstantInt::get (CGF.Int8Ty , 0 );
2832- for (auto Offset = PaddingInteval.First / CharWidth;
2833- Offset < PaddingInteval.Last / CharWidth; ++Offset) {
2834- auto *Index = ConstantInt::get (CGF.IntTy , Offset);
2835- auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2836- CGF.Builder .CreateAlignedStore (
2837- Zero, Element,
2838- CharUnits::One ().alignmentAtOffset (CharUnits::fromQuantity (Offset)));
2839- }
2828+
2829+
2830+ void ClearPadding (Value *Ptr, const BitInterval &PaddingInterval) {
2831+ auto *I8Ptr = CGF.Builder .CreateBitCast (Ptr, CGF.Int8PtrTy );
2832+ auto *Zero = ConstantInt::get (CGF.Int8Ty , 0 );
2833+
2834+ // Calculate byte indices and bit positions
2835+ auto StartByte = PaddingInterval.First / CharWidth;
2836+ auto StartBit = PaddingInterval.First % CharWidth;
2837+ auto EndByte = PaddingInterval.Last / CharWidth;
2838+ auto EndBit = PaddingInterval.Last % CharWidth;
2839+
2840+ if (StartByte == EndByte) {
2841+ // Interval is within a single byte
2842+ auto *Index = ConstantInt::get (CGF.IntTy , StartByte);
2843+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2844+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2845+
2846+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2847+
2848+ // Create mask to clear bits within the byte
2849+ uint8_t mask = ((1 << EndBit) - 1 ) & ~((1 << StartBit) - 1 );
2850+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , mask);
2851+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2852+
2853+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2854+ } else {
2855+ // Handle the start byte
2856+ if (StartBit != 0 ) {
2857+ auto *Index = ConstantInt::get (CGF.IntTy , StartByte);
2858+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2859+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2860+
2861+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2862+
2863+ uint8_t startMask = ((1 << (CharWidth - StartBit)) - 1 ) << StartBit;
2864+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , ~startMask);
2865+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2866+
2867+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2868+ ++StartByte;
2869+ }
2870+
2871+ // Handle full bytes in the middle
2872+ for (auto Offset = StartByte; Offset < EndByte; ++Offset) {
2873+ auto *Index = ConstantInt::get (CGF.IntTy , Offset);
2874+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2875+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2876+
2877+ CGF.Builder .CreateStore (Zero, ElementAddr);
2878+ }
2879+
2880+ // Handle the end byte
2881+ if (EndBit != 0 ) {
2882+ auto *Index = ConstantInt::get (CGF.IntTy , EndByte);
2883+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2884+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2885+
2886+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2887+
2888+ uint8_t endMask = (1 << EndBit) - 1 ;
2889+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , endMask);
2890+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2891+
2892+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2893+ }
2894+ }
28402895 }
28412896
2897+
28422898 CodeGenFunction &CGF;
28432899 const uint64_t CharWidth;
28442900 std::deque<Data> Queue;
0 commit comments