Skip to content

Commit c95ffad

Browse files
committed
[AssumeBundles] Use operand bundles to encode alignment assumptions
Summary: NOTE: There is a mailing list discussion on this: http://lists.llvm.org/pipermail/llvm-dev/2019-December/137632.html Complemantary to the assumption outliner prototype in D71692, this patch shows how we could simplify the code emitted for an alignemnt assumption. The generated code is smaller, less fragile, and it makes it easier to recognize the additional use as a "assumption use". As mentioned in D71692 and on the mailing list, we could adopt this scheme, and similar schemes for other patterns, without adopting the assumption outlining. Reviewers: hfinkel, xbolva00, lebedev.ri, nikic, rjmccall, spatel, jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: yamauchi, kuter, fhahn, merge_guards_bot, hiraditya, bollu, rkruppe, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D71739
1 parent 8938a6c commit c95ffad

34 files changed

+355
-620
lines changed

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,13 +2152,39 @@ void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
21522152
SourceLocation AssumptionLoc,
21532153
llvm::Value *Alignment,
21542154
llvm::Value *OffsetValue) {
2155-
llvm::Value *TheCheck;
2156-
llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
2157-
CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
2155+
if (Alignment->getType() != IntPtrTy)
2156+
Alignment =
2157+
Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");
2158+
if (OffsetValue && OffsetValue->getType() != IntPtrTy)
2159+
OffsetValue =
2160+
Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");
2161+
llvm::Value *TheCheck = nullptr;
21582162
if (SanOpts.has(SanitizerKind::Alignment)) {
2159-
emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
2160-
OffsetValue, TheCheck, Assumption);
2163+
llvm::Value *PtrIntValue =
2164+
Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
2165+
2166+
if (OffsetValue) {
2167+
bool IsOffsetZero = false;
2168+
if (const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2169+
IsOffsetZero = CI->isZero();
2170+
2171+
if (!IsOffsetZero)
2172+
PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
2173+
}
2174+
2175+
llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
2176+
llvm::Value *Mask =
2177+
Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));
2178+
llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
2179+
TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
21612180
}
2181+
llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
2182+
CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
2183+
2184+
if (!SanOpts.has(SanitizerKind::Alignment))
2185+
return;
2186+
emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
2187+
OffsetValue, TheCheck, Assumption);
21622188
}
21632189

21642190
void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,

clang/test/CodeGen/align_value.cpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ struct ad_struct {
2929
// CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8
3030
// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0
3131
// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8
32-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64
33-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
34-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
35-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
32+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ]
3633
// CHECK-NEXT: ret double* [[TMP1]]
3734
//
3835
double *foo(ad_struct& x) {
@@ -48,10 +45,7 @@ double *foo(ad_struct& x) {
4845
// CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8
4946
// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0
5047
// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8
51-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64
52-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
53-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
54-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
48+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ]
5549
// CHECK-NEXT: ret double* [[TMP1]]
5650
//
5751
double *goo(ad_struct *x) {
@@ -66,10 +60,7 @@ double *goo(ad_struct *x) {
6660
// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8
6761
// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8
6862
// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8
69-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64
70-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
71-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
72-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
63+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ]
7364
// CHECK-NEXT: ret double* [[TMP1]]
7465
//
7566
double *bar(aligned_double *x) {
@@ -84,10 +75,7 @@ double *bar(aligned_double *x) {
8475
// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8
8576
// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8
8677
// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8
87-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64
88-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
89-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
90-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
78+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ]
9179
// CHECK-NEXT: ret double* [[TMP1]]
9280
//
9381
double *car(aligned_double &x) {
@@ -103,10 +91,7 @@ double *car(aligned_double &x) {
10391
// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8
10492
// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double*, double** [[TMP0]], i64 5
10593
// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[ARRAYIDX]], align 8
106-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64
107-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
108-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
109-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
94+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ]
11095
// CHECK-NEXT: ret double* [[TMP1]]
11196
//
11297
double *dar(aligned_double *x) {
@@ -118,10 +103,7 @@ aligned_double eep();
118103
// CHECK-LABEL: define {{[^@]+}}@_Z3retv() #0
119104
// CHECK-NEXT: entry:
120105
// CHECK-NEXT: [[CALL:%.*]] = call double* @_Z3eepv()
121-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[CALL]] to i64
122-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
123-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
124-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
106+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[CALL]], i64 64) ]
125107
// CHECK-NEXT: ret double* [[CALL]]
126108
//
127109
double *ret() {

clang/test/CodeGen/alloc-align-attr.c

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@ __INT32_TYPE__*m1(__INT32_TYPE__ i) __attribute__((alloc_align(1)));
1111
// CHECK-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
1212
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
1313
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 [[TMP0]])
14-
// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = zext i32 [[TMP0]] to i64
15-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1
16-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
17-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
18-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
19-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
14+
// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64
15+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ]
2016
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4
2117
// CHECK-NEXT: ret i32 [[TMP1]]
2218
//
@@ -32,12 +28,8 @@ __INT32_TYPE__ test1(__INT32_TYPE__ a) {
3228
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
3329
// CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32
3430
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 [[CONV]])
35-
// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = zext i32 [[CONV]] to i64
36-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1
37-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
38-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
39-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
40-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
31+
// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = zext i32 [[CONV]] to i64
32+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ]
4133
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4
4234
// CHECK-NEXT: ret i32 [[TMP1]]
4335
//
@@ -55,11 +47,7 @@ __INT32_TYPE__ *m2(__SIZE_TYPE__ i) __attribute__((alloc_align(1)));
5547
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
5648
// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64
5749
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 [[CONV]])
58-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[CONV]], 1
59-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
60-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
61-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
62-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
50+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CONV]]) ]
6351
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4
6452
// CHECK-NEXT: ret i32 [[TMP1]]
6553
//
@@ -75,11 +63,7 @@ __INT32_TYPE__ test3(__INT32_TYPE__ a) {
7563
// CHECK-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8
7664
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
7765
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 [[TMP0]])
78-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[TMP0]], 1
79-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
80-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
81-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
82-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
66+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[TMP0]]) ]
8367
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4
8468
// CHECK-NEXT: ret i32 [[TMP1]]
8569
//
@@ -115,12 +99,8 @@ __INT32_TYPE__ *m3(struct Empty s, __int128_t i) __attribute__((alloc_align(2)))
11599
// CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 1
116100
// CHECK-NEXT: [[TMP8:%.*]] = load i64, i64* [[TMP7]], align 8
117101
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m3(i64 [[TMP6]], i64 [[TMP8]])
118-
// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = trunc i128 [[TMP3]] to i64
119-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1
120-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
121-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
122-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
123-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
102+
// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = trunc i128 [[TMP3]] to i64
103+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ]
124104
// CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[CALL]], align 4
125105
// CHECK-NEXT: ret i32 [[TMP9]]
126106
//
@@ -157,12 +137,8 @@ __INT32_TYPE__ *m4(struct MultiArgs s, __int128_t i) __attribute__((alloc_align(
157137
// CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP9]], i32 0, i32 1
158138
// CHECK-NEXT: [[TMP13:%.*]] = load i64, i64* [[TMP12]], align 8
159139
// CHECK-NEXT: [[CALL:%.*]] = call i32* @m4(i64 [[TMP6]], i64 [[TMP8]], i64 [[TMP11]], i64 [[TMP13]])
160-
// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = trunc i128 [[TMP3]] to i64
161-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1
162-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64
163-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
164-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
165-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
140+
// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = trunc i128 [[TMP3]] to i64
141+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ]
166142
// CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[CALL]], align 4
167143
// CHECK-NEXT: ret i32 [[TMP14]]
168144
//

clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,8 @@ void *t2_immediate2() {
3636
// CHECK-NEXT: store i32 [[ALIGNMENT:%.*]], i32* [[ALIGNMENT_ADDR]], align 4
3737
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ALIGNMENT_ADDR]], align 4
3838
// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @my_aligned_alloc(i32 320, i32 [[TMP0]])
39-
// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = zext i32 [[TMP0]] to i64
40-
// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1
41-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[CALL]] to i64
42-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]]
43-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
44-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
39+
// CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
40+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[CALL]], i64 [[TMP1]]) ]
4541
// CHECK-NEXT: ret i8* [[CALL]]
4642
//
4743
void *t3_variable(int alignment) {

clang/test/CodeGen/builtin-align-array.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,26 @@
44

55
extern int func(char *c);
66

7-
// CHECK-LABEL: define {{[^@]+}}@test_array() #0
7+
// CHECK-LABEL: @test_array(
88
// CHECK-NEXT: entry:
99
// CHECK-NEXT: [[BUF:%.*]] = alloca [1024 x i8], align 16
1010
// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 44
1111
// CHECK-NEXT: [[INTPTR:%.*]] = ptrtoint i8* [[ARRAYIDX]] to i64
1212
// CHECK-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[INTPTR]], -16
1313
// CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]]
1414
// CHECK-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[ARRAYIDX]], i64 [[DIFF]]
15-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[ALIGNED_RESULT]] to i64
16-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 15
17-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
18-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
15+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[ALIGNED_RESULT]], i64 16) ]
1916
// CHECK-NEXT: [[CALL:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT]])
2017
// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 22
2118
// CHECK-NEXT: [[INTPTR2:%.*]] = ptrtoint i8* [[ARRAYIDX1]] to i64
2219
// CHECK-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[INTPTR2]], 31
2320
// CHECK-NEXT: [[ALIGNED_INTPTR4:%.*]] = and i64 [[OVER_BOUNDARY]], -32
2421
// CHECK-NEXT: [[DIFF5:%.*]] = sub i64 [[ALIGNED_INTPTR4]], [[INTPTR2]]
2522
// CHECK-NEXT: [[ALIGNED_RESULT6:%.*]] = getelementptr inbounds i8, i8* [[ARRAYIDX1]], i64 [[DIFF5]]
26-
// CHECK-NEXT: [[PTRINT7:%.*]] = ptrtoint i8* [[ALIGNED_RESULT6]] to i64
27-
// CHECK-NEXT: [[MASKEDPTR8:%.*]] = and i64 [[PTRINT7]], 31
28-
// CHECK-NEXT: [[MASKCOND9:%.*]] = icmp eq i64 [[MASKEDPTR8]], 0
29-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND9]])
30-
// CHECK-NEXT: [[CALL10:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT6]])
31-
// CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 16
32-
// CHECK-NEXT: [[SRC_ADDR:%.*]] = ptrtoint i8* [[ARRAYIDX11]] to i64
23+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[ALIGNED_RESULT6]], i64 32) ]
24+
// CHECK-NEXT: [[CALL7:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT6]])
25+
// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 16
26+
// CHECK-NEXT: [[SRC_ADDR:%.*]] = ptrtoint i8* [[ARRAYIDX8]] to i64
3327
// CHECK-NEXT: [[SET_BITS:%.*]] = and i64 [[SRC_ADDR]], 63
3428
// CHECK-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0
3529
// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[IS_ALIGNED]] to i32
@@ -42,30 +36,24 @@ int test_array(void) {
4236
return __builtin_is_aligned(&buf[16], 64);
4337
}
4438

45-
// CHECK-LABEL: define {{[^@]+}}@test_array_should_not_mask() #0
39+
// CHECK-LABEL: @test_array_should_not_mask(
4640
// CHECK-NEXT: entry:
4741
// CHECK-NEXT: [[BUF:%.*]] = alloca [1024 x i8], align 32
4842
// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 64
4943
// CHECK-NEXT: [[INTPTR:%.*]] = ptrtoint i8* [[ARRAYIDX]] to i64
5044
// CHECK-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[INTPTR]], -16
5145
// CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]]
5246
// CHECK-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[ARRAYIDX]], i64 [[DIFF]]
53-
// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[ALIGNED_RESULT]] to i64
54-
// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 15
55-
// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
56-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]])
47+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[ALIGNED_RESULT]], i64 16) ]
5748
// CHECK-NEXT: [[CALL:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT]])
5849
// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BUF]], i64 0, i64 32
5950
// CHECK-NEXT: [[INTPTR2:%.*]] = ptrtoint i8* [[ARRAYIDX1]] to i64
6051
// CHECK-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[INTPTR2]], 31
6152
// CHECK-NEXT: [[ALIGNED_INTPTR4:%.*]] = and i64 [[OVER_BOUNDARY]], -32
6253
// CHECK-NEXT: [[DIFF5:%.*]] = sub i64 [[ALIGNED_INTPTR4]], [[INTPTR2]]
6354
// CHECK-NEXT: [[ALIGNED_RESULT6:%.*]] = getelementptr inbounds i8, i8* [[ARRAYIDX1]], i64 [[DIFF5]]
64-
// CHECK-NEXT: [[PTRINT7:%.*]] = ptrtoint i8* [[ALIGNED_RESULT6]] to i64
65-
// CHECK-NEXT: [[MASKEDPTR8:%.*]] = and i64 [[PTRINT7]], 31
66-
// CHECK-NEXT: [[MASKCOND9:%.*]] = icmp eq i64 [[MASKEDPTR8]], 0
67-
// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND9]])
68-
// CHECK-NEXT: [[CALL10:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT6]])
55+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[ALIGNED_RESULT6]], i64 32) ]
56+
// CHECK-NEXT: [[CALL7:%.*]] = call i32 @func(i8* [[ALIGNED_RESULT6]])
6957
// CHECK-NEXT: ret i32 1
7058
//
7159
int test_array_should_not_mask(void) {

0 commit comments

Comments
 (0)