@@ -2787,20 +2787,76 @@ struct PaddingClearer {
27872787 return Results;
27882788 }
27892789
2790- void ClearPadding (Value *Ptr, const BitInterval &PaddingInteval) {
2791- // TODO: support clearning non-one-byte clearing
2792- auto *I8Ptr = CGF.Builder .CreateBitCast (Ptr, CGF.Int8PtrTy );
2793- auto *Zero = ConstantInt::get (CGF.Int8Ty , 0 );
2794- for (auto Offset = PaddingInteval.First / CharWidth;
2795- Offset < PaddingInteval.Last / CharWidth; ++Offset) {
2796- auto *Index = ConstantInt::get (CGF.IntTy , Offset);
2797- auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2798- CGF.Builder .CreateAlignedStore (
2799- Zero, Element,
2800- CharUnits::One ().alignmentAtOffset (CharUnits::fromQuantity (Offset)));
2801- }
2790+
2791+
2792+ void ClearPadding (Value *Ptr, const BitInterval &PaddingInterval) {
2793+ auto *I8Ptr = CGF.Builder .CreateBitCast (Ptr, CGF.Int8PtrTy );
2794+ auto *Zero = ConstantInt::get (CGF.Int8Ty , 0 );
2795+
2796+ // Calculate byte indices and bit positions
2797+ auto StartByte = PaddingInterval.First / CharWidth;
2798+ auto StartBit = PaddingInterval.First % CharWidth;
2799+ auto EndByte = PaddingInterval.Last / CharWidth;
2800+ auto EndBit = PaddingInterval.Last % CharWidth;
2801+
2802+ if (StartByte == EndByte) {
2803+ // Interval is within a single byte
2804+ auto *Index = ConstantInt::get (CGF.IntTy , StartByte);
2805+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2806+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2807+
2808+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2809+
2810+ // Create mask to clear bits within the byte
2811+ uint8_t mask = ((1 << EndBit) - 1 ) & ~((1 << StartBit) - 1 );
2812+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , mask);
2813+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2814+
2815+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2816+ } else {
2817+ // Handle the start byte
2818+ if (StartBit != 0 ) {
2819+ auto *Index = ConstantInt::get (CGF.IntTy , StartByte);
2820+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2821+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2822+
2823+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2824+
2825+ uint8_t startMask = ((1 << (CharWidth - StartBit)) - 1 ) << StartBit;
2826+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , ~startMask);
2827+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2828+
2829+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2830+ ++StartByte;
2831+ }
2832+
2833+ // Handle full bytes in the middle
2834+ for (auto Offset = StartByte; Offset < EndByte; ++Offset) {
2835+ auto *Index = ConstantInt::get (CGF.IntTy , Offset);
2836+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2837+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2838+
2839+ CGF.Builder .CreateStore (Zero, ElementAddr);
2840+ }
2841+
2842+ // Handle the end byte
2843+ if (EndBit != 0 ) {
2844+ auto *Index = ConstantInt::get (CGF.IntTy , EndByte);
2845+ auto *Element = CGF.Builder .CreateGEP (CGF.Int8Ty , I8Ptr, Index);
2846+ Address ElementAddr (Element, CGF.Int8Ty , CharUnits::One ());
2847+
2848+ auto *Value = CGF.Builder .CreateLoad (ElementAddr);
2849+
2850+ uint8_t endMask = (1 << EndBit) - 1 ;
2851+ auto *MaskValue = ConstantInt::get (CGF.Int8Ty , endMask);
2852+ auto *NewValue = CGF.Builder .CreateAnd (Value, MaskValue);
2853+
2854+ CGF.Builder .CreateStore (NewValue, ElementAddr);
2855+ }
2856+ }
28022857 }
28032858
2859+
28042860 CodeGenFunction &CGF;
28052861 const uint64_t CharWidth;
28062862 std::deque<Data> Queue;
0 commit comments