Skip to content

Commit a3bbab1

Browse files
authored
[IR] Don't mark experimental.guard as willreturn (#69433)
Control flow does not necessary continue past guard intrinsics, so don't mark them as willreturn. This fixes the miscompile in the sdiv-guard.ll test.
1 parent 39427b1 commit a3bbab1

File tree

4 files changed

+15
-12
lines changed

4 files changed

+15
-12
lines changed

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1697,7 +1697,7 @@ def int_experimental_deoptimize : Intrinsic<[llvm_any_ty], [llvm_vararg_ty],
16971697
[Throws]>;
16981698

16991699
// Support for speculative runtime guards
1700-
def int_experimental_guard : DefaultAttrsIntrinsic<[], [llvm_i1_ty, llvm_vararg_ty],
1700+
def int_experimental_guard : Intrinsic<[], [llvm_i1_ty, llvm_vararg_ty],
17011701
[Throws]>;
17021702

17031703
// Supports widenable conditions for guards represented as explicit branches.

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,16 @@ bool llvm::wouldInstructionBeTriviallyDead(const Instruction *I,
443443
if (!II)
444444
return false;
445445

446+
switch (II->getIntrinsicID()) {
447+
case Intrinsic::experimental_guard: {
448+
// Guards on true are operationally no-ops. In the future we can
449+
// consider more sophisticated tradeoffs for guards considering potential
450+
// for check widening, but for now we keep things simple.
451+
auto *Cond = dyn_cast<ConstantInt>(II->getArgOperand(0));
452+
return Cond && Cond->isOne();
453+
}
446454
// TODO: These intrinsics are not safe to remove, because this may remove
447455
// a well-defined trap.
448-
switch (II->getIntrinsicID()) {
449456
case Intrinsic::wasm_trunc_signed:
450457
case Intrinsic::wasm_trunc_unsigned:
451458
case Intrinsic::ptrauth_auth:
@@ -484,13 +491,9 @@ bool llvm::wouldInstructionBeTriviallyDead(const Instruction *I,
484491
return false;
485492
}
486493

487-
// Assumptions are dead if their condition is trivially true. Guards on
488-
// true are operationally no-ops. In the future we can consider more
489-
// sophisticated tradeoffs for guards considering potential for check
490-
// widening, but for now we keep things simple.
491-
if ((II->getIntrinsicID() == Intrinsic::assume &&
492-
isAssumeWithEmptyBundle(cast<AssumeInst>(*II))) ||
493-
II->getIntrinsicID() == Intrinsic::experimental_guard) {
494+
// Assumptions are dead if their condition is trivially true.
495+
if (II->getIntrinsicID() == Intrinsic::assume &&
496+
isAssumeWithEmptyBundle(cast<AssumeInst>(*II))) {
494497
if (ConstantInt *Cond = dyn_cast<ConstantInt>(II->getArgOperand(0)))
495498
return !Cond->isZero();
496499

llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ declare void @llvm.experimental.guard(i1, ...)
185185
; CHECK: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
186186
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
187187
; CHECK: attributes #[[ATTR2]] = { nounwind }
188-
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync willreturn }
189188
;.
190189
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
191190
; CGSCC: {{.*}}

llvm/test/Transforms/InstCombine/sdiv-guard.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ declare void @llvm.experimental.guard(i1, ...)
66
; Regression test. If %flag is false then %s == 0 and guard should be triggered.
77
define i32 @a(i1 %flag, i32 %X) nounwind readnone {
88
; CHECK-LABEL: @a(
9-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
10-
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) #[[ATTR2:[0-9]+]] [ "deopt"() ]
9+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], 0
10+
; CHECK-NEXT: [[CMP:%.*]] = select i1 [[FLAG:%.*]], i1 [[CMP1]], i1 false
11+
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) #[[ATTR1:[0-9]+]] [ "deopt"() ]
1112
; CHECK-NEXT: [[R:%.*]] = sdiv i32 100, [[X]]
1213
; CHECK-NEXT: ret i32 [[R]]
1314
;

0 commit comments

Comments
 (0)