Skip to content

Commit f6437f2

Browse files
authored
Merge pull request #21054 from aschwaighofer/fix_enum_gatherbits_5.0
[5.0] IRGen: gatherbits - extend the bits before we shift left
2 parents ae24917 + ab2d143 commit f6437f2

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

lib/IRGen/EnumPayload.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,10 @@ llvm::Value *irgen::emitGatherSpareBits(IRGenFunction &IGF,
719719
llvm::Value *newBits;
720720
if (u > usedBits)
721721
newBits = IGF.Builder.CreateLShr(spareBits, u - usedBits);
722-
else if (u < usedBits)
723-
newBits = IGF.Builder.CreateShl(spareBits, usedBits - u);
724-
else
722+
else if (u < usedBits) {
723+
newBits = IGF.Builder.CreateZExtOrTrunc(spareBits, destTy);
724+
newBits = IGF.Builder.CreateShl(newBits, usedBits - u);
725+
} else
725726
newBits = spareBits;
726727
newBits = IGF.Builder.CreateZExtOrTrunc(newBits, destTy);
727728

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-swift-frontend -enable-objc-interop -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir | %FileCheck %s
2+
3+
// REQUIRES: CPU=x86_64
4+
5+
class Tag {}
6+
7+
struct Scalar {
8+
var str = ""
9+
var x = Tag()
10+
var style: BinaryChoice = .zero
11+
enum BinaryChoice: UInt32 {
12+
case zero = 0
13+
case one
14+
}
15+
}
16+
17+
public struct Sequence {
18+
var tag: Tag = Tag()
19+
var tag2: Tag = Tag()
20+
}
21+
22+
enum Node {
23+
case scalar(Scalar)
24+
case sequence(Sequence)
25+
}
26+
27+
// CHECK: define internal i32 @"$s22multi_payload_shifting4NodeOwet"(%swift.opaque* noalias %value, i32 %numEmptyCases, %swift.type* %Node)
28+
// CHECK: [[ADDR:%.*]] = getelementptr inbounds { i64, i64, i64, i8 }, { i64, i64, i64, i8 }* {{.*}}, i32 0, i32 3
29+
// CHECK: [[BYTE:%.*]] = load i8, i8* [[ADDR]]
30+
// Make sure we zext before we shift.
31+
// CHECK: [[ZEXT:%.*]] = zext i8 [[BYTE]] to i32
32+
// CHECK: shl i32 [[ZEXT]], 10
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-run-simple-swift
2+
3+
// REQUIRES: executable_test
4+
5+
import Swift
6+
import StdlibUnittest
7+
8+
class Tag {}
9+
10+
struct Scalar {
11+
var str = ""
12+
var x = Tag()
13+
var style: BinaryChoice = .zero
14+
enum BinaryChoice: UInt32 {
15+
case zero = 0
16+
case one
17+
}
18+
}
19+
20+
public struct Sequence {
21+
var tag: Tag = Tag()
22+
var tag2: Tag = Tag()
23+
}
24+
25+
enum Node {
26+
case scalar(Scalar)
27+
case sequence(Sequence)
28+
}
29+
30+
func createOptionalNodeNil<T>(_ t: T) -> T? {
31+
return nil
32+
}
33+
34+
func isNil<T>(_ t: T?) -> Bool {
35+
return t == nil
36+
}
37+
38+
var tests = TestSuite("extra inhabitants shifts")
39+
40+
41+
tests.test("test-shift-fix") {
42+
let opt = createOptionalNodeNil(Node.scalar(Scalar()))
43+
var res = false
44+
if isNil(opt) {
45+
res = true
46+
}
47+
expectEqual(true, res)
48+
}
49+
50+
runAllTests()

0 commit comments

Comments
 (0)