Skip to content

Commit 11f9d19

Browse files
committed
IRGen: gatherbits - extend the bits before we shift left
SR-9335 rdar://46264497
1 parent b3ca057 commit 11f9d19

File tree

3 files changed

+89
-3
lines changed

3 files changed

+89
-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) #9 {
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: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift -o %t/a.out %s
4+
// RUN: %target-run %t/a.out 2>&1
5+
6+
// REQUIRES: executable_test
7+
8+
import Swift
9+
import StdlibUnittest
10+
11+
class Tag {}
12+
13+
struct Scalar {
14+
var str = ""
15+
var x = Tag()
16+
var style: BinaryChoice = .zero
17+
enum BinaryChoice: UInt32 {
18+
case zero = 0
19+
case one
20+
}
21+
}
22+
23+
public struct Sequence {
24+
var tag: Tag = Tag()
25+
var tag2: Tag = Tag()
26+
}
27+
28+
enum Node {
29+
case scalar(Scalar)
30+
case sequence(Sequence)
31+
}
32+
33+
func createOptionalNodeNil<T>(_ t: T) -> T? {
34+
return nil
35+
}
36+
37+
func isNil<T>(_ t: T?) -> Bool {
38+
return t == nil
39+
}
40+
41+
var tests = TestSuite("extra inhabitants shifts")
42+
43+
44+
tests.test("test-shift-fix") {
45+
let opt = createOptionalNodeNil(Node.scalar(Scalar()))
46+
var res = false
47+
if isNil(opt) {
48+
res = true
49+
}
50+
expectEqual(true, res)
51+
}
52+
53+
runAllTests()

0 commit comments

Comments
 (0)