diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index b32a27f9555fd..41c2c1a9a0416 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3013,6 +3013,8 @@ assumptions, such as that a :ref:`parameter attribute ` or a location. Operand bundles enable assumptions that are either hard or impossible to represent as a boolean argument of an :ref:`llvm.assume `. +Assumes with operand bundles must have ``i1 true`` as the condition operand. + An assume operand bundle has the form: :: @@ -3045,7 +3047,7 @@ allows the optimizer to assume that at location of call to .. code-block:: llvm - call void @llvm.assume(i1 %cond) ["cold"(), "nonnull"(ptr %val)] + call void @llvm.assume(i1 true) ["cold"(), "nonnull"(ptr %val)] allows the optimizer to assume that the :ref:`llvm.assume ` call location is cold and that ``%val`` may not be null. diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 9bde965d660a4..0c6175b1945cc 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5675,6 +5675,11 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { default: break; case Intrinsic::assume: { + if (Call.hasOperandBundles()) { + auto *Cond = dyn_cast(Call.getArgOperand(0)); + Check(Cond && Cond->isOne(), + "assume with operand bundles must have i1 true condition", Call); + } for (auto &Elem : Call.bundle_op_infos()) { unsigned ArgCount = Elem.End - Elem.Begin; // Separate storage assumptions are special insofar as they're the only diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/domtree-crash.ll b/llvm/test/Transforms/AlignmentFromAssumptions/domtree-crash.ll index c7fc1dc699671..f9b9dd13b0d0c 100644 --- a/llvm/test/Transforms/AlignmentFromAssumptions/domtree-crash.ll +++ b/llvm/test/Transforms/AlignmentFromAssumptions/domtree-crash.ll @@ -9,10 +9,10 @@ define void @fn1() { ; CHECK-LABEL: define void @fn1() { -; CHECK-NEXT: call void @llvm.assume(i1 false) [ "align"(ptr @global, i64 1) ] +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr @global, i64 1) ] ; CHECK-NEXT: ret void ; - call void @llvm.assume(i1 false) [ "align"(ptr @global, i64 1) ] + call void @llvm.assume(i1 true) [ "align"(ptr @global, i64 1) ] ret void } diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll index e87a61a57ea47..7b0b871513513 100644 --- a/llvm/test/Transforms/InstCombine/assume.ll +++ b/llvm/test/Transforms/InstCombine/assume.ll @@ -498,13 +498,13 @@ not_taken: define i1 @nonnull3B(ptr %a, i1 %control) { ; CHECK-LABEL: @nonnull3B( ; CHECK-NEXT: entry: +; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[A:%.*]], align 8 ; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] ; CHECK: taken: -; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[A:%.*]], align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null -; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) [ "nonnull"(ptr [[LOAD]]) ] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[LOAD]]) ] +; CHECK-NEXT: ret i1 true ; CHECK: not_taken: +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[LOAD]]) ] ; CHECK-NEXT: ret i1 false ; entry: @@ -512,10 +512,10 @@ entry: %cmp = icmp ne ptr %load, null br i1 %control, label %taken, label %not_taken taken: - call void @llvm.assume(i1 %cmp) ["nonnull"(ptr %load)] + call void @llvm.assume(i1 true) ["nonnull"(ptr %load)] ret i1 %cmp not_taken: - call void @llvm.assume(i1 %cmp) ["nonnull"(ptr %load)] + call void @llvm.assume(i1 true) ["nonnull"(ptr %load)] ret i1 %control } @@ -544,7 +544,7 @@ taken: br label %exit exit: ; FIXME: this shouldn't be dropped because it is still dominated by the new position of %load - call void @llvm.assume(i1 %cmp) ["nonnull"(ptr %load)] + call void @llvm.assume(i1 %cmp) ret i1 %cmp2 not_taken: call void @llvm.assume(i1 %cmp) @@ -575,7 +575,7 @@ taken: exit: ret i1 %cmp2 not_taken: - call void @llvm.assume(i1 %cmp) ["nonnull"(ptr %load)] + call void @llvm.assume(i1 %cmp) ret i1 %control } diff --git a/llvm/test/Verifier/assume-bundles.ll b/llvm/test/Verifier/assume-bundles.ll index d8037b965edb5..728b118c99fb6 100644 --- a/llvm/test/Verifier/assume-bundles.ll +++ b/llvm/test/Verifier/assume-bundles.ll @@ -3,7 +3,7 @@ declare void @llvm.assume(i1) -define void @func(ptr %P, i32 %P1, ptr %P2, ptr %P3) { +define void @func(ptr %P, i32 %P1, ptr %P2, ptr %P3, i1 %cond) { ; CHECK: tags must be valid attribute names ; CHECK: "adazdazd" call void @llvm.assume(i1 true) ["adazdazd"()] @@ -32,5 +32,7 @@ define void @func(ptr %P, i32 %P1, ptr %P2, ptr %P3) { call void @llvm.assume(i1 true) ["separate_storage"(ptr %P, i32 123)] ; CHECK: dereferenceable assumptions should have 2 arguments call void @llvm.assume(i1 true) ["align"(ptr %P, i32 4), "dereferenceable"(ptr %P)] +; CHECK: assume with operand bundles must have i1 true condition + call void @llvm.assume(i1 %cond) ["nonnull"(ptr %P)] ret void } diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll index e5f92e4337154..d2bb80982bb3d 100644 --- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll @@ -733,12 +733,12 @@ define void @assume(i1 %true) { } ; CHECK-LABEL: @assume_with_opbundles -; CHECK-SAME: %[[TRUE:[a-zA-Z0-9]+]] ; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]] -define void @assume_with_opbundles(i1 %true, ptr %p) { +define void @assume_with_opbundles(ptr %p) { + ; CHECK: %[[TRUE:.+]] = llvm.mlir.constant(true) : i1 ; CHECK: %[[ALIGN:.+]] = llvm.mlir.constant(8 : i32) : i32 ; CHECK: llvm.intr.assume %[[TRUE]] ["align"(%[[PTR]], %[[ALIGN]] : !llvm.ptr, i32)] : i1 - call void @llvm.assume(i1 %true) ["align"(ptr %p, i32 8)] + call void @llvm.assume(i1 true) ["align"(ptr %p, i32 8)] ret void } diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir index 01aa740452b62..cf3e129879d09 100644 --- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir @@ -460,10 +460,11 @@ llvm.func @assume_without_opbundles(%cond: i1) { } // CHECK-LABEL: @assume_with_opbundles -llvm.func @assume_with_opbundles(%cond: i1, %p: !llvm.ptr) { +llvm.func @assume_with_opbundles(%p: !llvm.ptr) { + %true = llvm.mlir.constant(true) : i1 %0 = llvm.mlir.constant(8 : i32) : i32 - // CHECK: call void @llvm.assume(i1 %{{.+}}) [ "align"(ptr %{{.+}}, i32 8) ] - llvm.intr.assume %cond ["align"(%p, %0 : !llvm.ptr, i32)] : i1 + // CHECK: call void @llvm.assume(i1 true) [ "align"(ptr %{{.+}}, i32 8) ] + llvm.intr.assume %true ["align"(%p, %0 : !llvm.ptr, i32)] : i1 llvm.return }