Skip to content

Commit 12bf183

Browse files
committed
[AutoUpgrade] Gracefully handle invalid alignment on masked intrinsics
Generate a usage error instead of asserting.
1 parent 20340ac commit 12bf183

File tree

2 files changed

+71
-8
lines changed

2 files changed

+71
-8
lines changed

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,33 +5262,47 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
52625262
return;
52635263
}
52645264

5265+
auto GetMaybeAlign = [](Value *Op) {
5266+
if (auto *CI = dyn_cast<ConstantInt>(Op)) {
5267+
uint64_t Val = CI->getZExtValue();
5268+
if (Val == 0)
5269+
return MaybeAlign();
5270+
if (isPowerOf2_64(Val))
5271+
return MaybeAlign(Val);
5272+
}
5273+
reportFatalUsageError("Invalid alignment argument");
5274+
};
5275+
auto GetAlign = [&](Value *Op) {
5276+
MaybeAlign Align = GetMaybeAlign(Op);
5277+
if (Align)
5278+
return *Align;
5279+
reportFatalUsageError("Invalid zero alignment argument");
5280+
};
5281+
52655282
const DataLayout &DL = CI->getDataLayout();
52665283
switch (NewFn->getIntrinsicID()) {
52675284
case Intrinsic::masked_load:
52685285
NewCall = Builder.CreateMaskedLoad(
5269-
CI->getType(), CI->getArgOperand(0),
5270-
cast<ConstantInt>(CI->getArgOperand(1))->getAlignValue(),
5286+
CI->getType(), CI->getArgOperand(0), GetAlign(CI->getArgOperand(1)),
52715287
CI->getArgOperand(2), CI->getArgOperand(3));
52725288
break;
52735289
case Intrinsic::masked_gather:
52745290
NewCall = Builder.CreateMaskedGather(
52755291
CI->getType(), CI->getArgOperand(0),
5276-
DL.getValueOrABITypeAlignment(
5277-
cast<ConstantInt>(CI->getArgOperand(1))->getMaybeAlignValue(),
5278-
CI->getType()->getScalarType()),
5292+
DL.getValueOrABITypeAlignment(GetMaybeAlign(CI->getArgOperand(1)),
5293+
CI->getType()->getScalarType()),
52795294
CI->getArgOperand(2), CI->getArgOperand(3));
52805295
break;
52815296
case Intrinsic::masked_store:
52825297
NewCall = Builder.CreateMaskedStore(
52835298
CI->getArgOperand(0), CI->getArgOperand(1),
5284-
cast<ConstantInt>(CI->getArgOperand(2))->getAlignValue(),
5285-
CI->getArgOperand(3));
5299+
GetAlign(CI->getArgOperand(2)), CI->getArgOperand(3));
52865300
break;
52875301
case Intrinsic::masked_scatter:
52885302
NewCall = Builder.CreateMaskedScatter(
52895303
CI->getArgOperand(0), CI->getArgOperand(1),
52905304
DL.getValueOrABITypeAlignment(
5291-
cast<ConstantInt>(CI->getArgOperand(2))->getMaybeAlignValue(),
5305+
GetMaybeAlign(CI->getArgOperand(2)),
52925306
CI->getArgOperand(0)->getType()->getScalarType()),
52935307
CI->getArgOperand(3));
52945308
break;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; RUN: split-file %s %t
2+
; RUN: not llvm-as < %t/masked-store.ll 2>&1 | FileCheck %s --check-prefix=MASKED-STORE
3+
; RUN: not llvm-as < %t/masked-store-zero.ll 2>&1 | FileCheck %s --check-prefix=MASKED-STORE-ZERO
4+
; RUN: not llvm-as < %t/masked-load.ll 2>&1 | FileCheck %s --check-prefix=MASKED-LOAD
5+
; RUN: not llvm-as < %t/masked-load-zero.ll 2>&1 | FileCheck %s --check-prefix=MASKED-LOAD-ZERO
6+
; RUN: not llvm-as < %t/masked-scatter.ll 2>&1 | FileCheck %s --check-prefix=MASKED-SCATTER
7+
; RUN: not llvm-as < %t/masked-gather.ll 2>&1 | FileCheck %s --check-prefix=MASKED-GATHER
8+
9+
;--- masked-store.ll
10+
; MASKED-STORE: LLVM ERROR: Invalid alignment argument
11+
define void @masked_store(ptr %ptr, <2 x i1> %mask, <2 x double> %val) {
12+
call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 3, <2 x i1> %mask)
13+
ret void
14+
}
15+
16+
;--- masked-store-zero.ll
17+
; MASKED-STORE-ZERO: LLVM ERROR: Invalid zero alignment argument
18+
define void @masked_store_zero(ptr %ptr, <2 x i1> %mask, <2 x double> %val) {
19+
call void @llvm.masked.store.v2f64.p0(<2 x double> %val, ptr %ptr, i32 0, <2 x i1> %mask)
20+
ret void
21+
}
22+
23+
;--- masked-load.ll
24+
; MASKED-LOAD: LLVM ERROR: Invalid alignment argument
25+
define void @masked_load(ptr %ptr, <2 x i1> %mask, <2 x double> %val) {
26+
call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 3, <2 x i1> %mask, <2 x double> %val)
27+
ret void
28+
}
29+
30+
;--- masked-load-zero.ll
31+
; MASKED-LOAD-ZERO: LLVM ERROR: Invalid zero alignment argument
32+
define void @masked_load_zero(ptr %ptr, <2 x i1> %mask, <2 x double> %val) {
33+
call <2 x double> @llvm.masked.load.v2f64.p0(ptr %ptr, i32 0, <2 x i1> %mask, <2 x double> %val)
34+
ret void
35+
}
36+
37+
;--- masked-scatter.ll
38+
; MASKED-SCATTER: LLVM ERROR: Invalid alignment argument
39+
define void @masked_scatter(<2 x ptr> %ptr, <2 x i1> %mask, <2 x double> %val) {
40+
call void @llvm.masked.scatter.v2f64.p0(<2 x double> %val, <2 x ptr> %ptr, i32 3, <2 x i1> %mask)
41+
ret void
42+
}
43+
44+
;--- masked-gather.ll
45+
; MASKED-GATHER: LLVM ERROR: Invalid alignment argument
46+
define void @masked_gather(<2 x ptr> %ptr, <2 x i1> %mask, <2 x double> %val) {
47+
call <2 x double> @llvm.masked.gather.v2f64.p0(<2 x ptr> %ptr, i32 3, <2 x i1> %mask, <2 x double> %val)
48+
ret void
49+
}

0 commit comments

Comments
 (0)