Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -4558,10 +4558,11 @@ const auto *AlignmentCI = dyn_cast(Alignment); if (!AlignmentCI) return Attrs; - // We may legitimately have non-power-of-2 alignment here. - // If so, this is UB land, emit it via `@llvm.assume` instead. - if (!AlignmentCI->getValue().isPowerOf2()) + // Non power-of-2 alignment is UB and rejected by the IR verifier. + if (!AlignmentCI->getValue().isPowerOf2()) { + AA = nullptr; // We're done. Disallow doing anything else. return Attrs; + } llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute( CGF.getLLVMContext(), Attrs, llvm::Align( Index: clang/test/CodeGen/non-power-of-2-alignment-assumptions.c =================================================================== --- clang/test/CodeGen/non-power-of-2-alignment-assumptions.c +++ clang/test/CodeGen/non-power-of-2-alignment-assumptions.c @@ -21,7 +21,6 @@ // CHECK-NEXT: [[ALIGN_ADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[ALIGN:%.*]], i32* [[ALIGN_ADDR]], align 4 // CHECK-NEXT: [[CALL:%.*]] = call i8* @alloc(i32 7) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[CALL]], i64 7) ] // CHECK-NEXT: ret void // void t1(int align) { Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -4610,12 +4610,16 @@ "first argument should be a pointer"); Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(), "second argument should be an integer"); + ConstantInt *Alignment = dyn_cast(Call.getOperand(Elem.Begin + 1)); + if (Alignment) + Assert(Alignment->getValue().isPowerOf2(), + "alignment must be a power of 2", Call); if (ArgCount == 3) Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(), "third argument should be an integer if present"); return; } - Assert(ArgCount <= 2, "to many arguments"); + Assert(ArgCount <= 2, "too many arguments"); if (Kind == Attribute::None) break; if (Attribute::isIntAttrKind(Kind)) { Index: llvm/test/Verifier/assume-bundles.ll =================================================================== --- llvm/test/Verifier/assume-bundles.ll +++ llvm/test/Verifier/assume-bundles.ll @@ -8,7 +8,7 @@ call void @llvm.assume(i1 true) ["adazdazd"()] ; CHECK: the second argument should be a constant integral value call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 %P1)] -; CHECK: to many arguments +; CHECK: too many arguments call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 8, i32 8)] ; CHECK: this attribute should have 2 arguments call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P)] @@ -21,6 +21,8 @@ call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1, i32 4, i32 4)] ; CHECK: second argument should be an integer call void @llvm.assume(i1 true) ["align"(i32* %P, i32* %P2)] +; CHECK: alignment must be a power of 2 + call void @llvm.assume(i1 true) ["align"(i32* %P, i32 7)] ; CHECK: third argument should be an integer if present call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1, i32* %P2)] ret void