https://github.com/janagor updated https://github.com/llvm/llvm-project/pull/133546
From 4581169d6fbe72357bb83b95fe36c8cc606efa1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Fri, 28 Mar 2025 23:36:18 +0100 Subject: [PATCH 1/6] [clang][CodeGen] Added llvm ir pre-commit test. --- clang/test/CodeGen/atomic-ops-load.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 clang/test/CodeGen/atomic-ops-load.c diff --git a/clang/test/CodeGen/atomic-ops-load.c b/clang/test/CodeGen/atomic-ops-load.c new file mode 100644 index 0000000000000..adcaf9a2112fa --- /dev/null +++ b/clang/test/CodeGen/atomic-ops-load.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple riscv64 -O1 -emit-llvm %s -o - | FileCheck %s +#include <stdbool.h> + +extern bool t1; +bool test1(void) { +// CHECK-LABEL: define{{.*}} i1 @test1 +// CHECK: load atomic i8, ptr @t1 monotonic, align 1 +// CHECK-NEXT: trunc i8 %{{.*}} to i1 +// CHECK-NEXT: ret i1 %{{.*}} + return __atomic_load_n(&t1, __ATOMIC_RELAXED); +} From 852b691fac487b3cef7b0df8875c26573bc58daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Sat, 29 Mar 2025 00:53:23 +0100 Subject: [PATCH 2/6] [clang][CodeGen] Added `!range` metadata to atomic load for `bool`. --- clang/lib/CodeGen/CGAtomic.cpp | 23 +++++++++++++++++++++++ clang/test/CodeGen/atomic-ops-load.c | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 3adb2a7ad207f..70ae7180a9adc 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -590,6 +590,29 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); Load->setAtomic(Order, Scope); Load->setVolatile(E->isVolatile()); + + if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { + CGF.Builder.CreateStore(Load, Dest); + return; + } + + QualType Ty = E->getValueType(); + if (!Ty->isBooleanType()) { + CGF.Builder.CreateStore(Load, Dest); + return; + } + + llvm::MDBuilder MDHelper(CGF.getLLVMContext()); + llvm::APInt BooleanMin = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0); + llvm::APInt BooleanEnd = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2); + + if (llvm::MDNode *RangeInfo = + MDHelper.createRange(BooleanMin, BooleanEnd)) { + Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); + Load->setMetadata(llvm::LLVMContext::MD_noundef, + llvm::MDNode::get(CGF.getLLVMContext(), {})); + } + CGF.Builder.CreateStore(Load, Dest); return; } diff --git a/clang/test/CodeGen/atomic-ops-load.c b/clang/test/CodeGen/atomic-ops-load.c index adcaf9a2112fa..778a7ebdc2618 100644 --- a/clang/test/CodeGen/atomic-ops-load.c +++ b/clang/test/CodeGen/atomic-ops-load.c @@ -4,8 +4,8 @@ extern bool t1; bool test1(void) { // CHECK-LABEL: define{{.*}} i1 @test1 -// CHECK: load atomic i8, ptr @t1 monotonic, align 1 -// CHECK-NEXT: trunc i8 %{{.*}} to i1 +// CHECK: load atomic i8, ptr @t1 monotonic, align 1, !range ![[$WS_RANGE:[0-9]*]], !noundef !{{[0-9]+}} +// CHECK-NEXT: trunc nuw i8 %{{.*}} to i1 // CHECK-NEXT: ret i1 %{{.*}} return __atomic_load_n(&t1, __ATOMIC_RELAXED); } From e42772bbc0851696d73ded4abc3edf651f4e8b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Sat, 29 Mar 2025 01:12:18 +0100 Subject: [PATCH 3/6] Updated codestyle. --- clang/lib/CodeGen/CGAtomic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 70ae7180a9adc..2c9613deef744 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -607,10 +607,10 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::APInt BooleanEnd = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2); if (llvm::MDNode *RangeInfo = - MDHelper.createRange(BooleanMin, BooleanEnd)) { + MDHelper.createRange(BooleanMin, BooleanEnd)) { Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); Load->setMetadata(llvm::LLVMContext::MD_noundef, - llvm::MDNode::get(CGF.getLLVMContext(), {})); + llvm::MDNode::get(CGF.getLLVMContext(), {})); } CGF.Builder.CreateStore(Load, Dest); From c95f16cf2df51e8f7a1d4952918c977104271072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Fri, 4 Apr 2025 11:20:30 +0200 Subject: [PATCH 4/6] Refactored early returns into normal if statement. --- clang/lib/CodeGen/CGAtomic.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 2c9613deef744..c40bf3cd77d86 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -591,26 +591,17 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, Load->setAtomic(Order, Scope); Load->setVolatile(E->isVolatile()); - if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { - CGF.Builder.CreateStore(Load, Dest); - return; - } - QualType Ty = E->getValueType(); - if (!Ty->isBooleanType()) { - CGF.Builder.CreateStore(Load, Dest); - return; - } - - llvm::MDBuilder MDHelper(CGF.getLLVMContext()); - llvm::APInt BooleanMin = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0); - llvm::APInt BooleanEnd = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2); - - if (llvm::MDNode *RangeInfo = - MDHelper.createRange(BooleanMin, BooleanEnd)) { - Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); - Load->setMetadata(llvm::LLVMContext::MD_noundef, - llvm::MDNode::get(CGF.getLLVMContext(), {})); + if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && Ty->isBooleanType()) { + llvm::MDBuilder MDHelper(CGF.getLLVMContext()); + llvm::APInt BooleanMin = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0); + llvm::APInt BooleanEnd = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2); + if (llvm::MDNode *RangeInfo = + MDHelper.createRange(BooleanMin, BooleanEnd)) { + Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); + Load->setMetadata(llvm::LLVMContext::MD_noundef, + llvm::MDNode::get(CGF.getLLVMContext(), {})); + } } CGF.Builder.CreateStore(Load, Dest); From ecc0f4060b9192128837539ddab9797922cc5955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Thu, 10 Apr 2025 11:51:38 +0200 Subject: [PATCH 5/6] Reverted adding `range!` metadata from 852b691fac48. Added `isSafeNUWTrunc` helper to `EmitFromMemory` to allow adding `nuw` to `load` when safe. --- clang/lib/CodeGen/CGAtomic.cpp | 14 ----- clang/lib/CodeGen/CGExpr.cpp | 58 ++++++++++++++++++- clang/test/C/drs/dr335.c | 2 +- clang/test/CodeGen/PowerPC/bool_test.c | 2 +- clang/test/CodeGen/atomic-ops-load.c | 2 +- .../attr-likelihood-if-branch-weights.cpp | 32 +++++----- clang/test/CodeGenObjC/arc-ternary-op.m | 2 +- 7 files changed, 76 insertions(+), 36 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index c40bf3cd77d86..3adb2a7ad207f 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -590,20 +590,6 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); Load->setAtomic(Order, Scope); Load->setVolatile(E->isVolatile()); - - QualType Ty = E->getValueType(); - if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && Ty->isBooleanType()) { - llvm::MDBuilder MDHelper(CGF.getLLVMContext()); - llvm::APInt BooleanMin = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0); - llvm::APInt BooleanEnd = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2); - if (llvm::MDNode *RangeInfo = - MDHelper.createRange(BooleanMin, BooleanEnd)) { - Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); - Load->setMetadata(llvm::LLVMContext::MD_noundef, - llvm::MDNode::get(CGF.getLLVMContext(), {})); - } - } - CGF.Builder.CreateStore(Load, Dest); return; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 3d3a111f0514a..f6d0442261eb7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2093,6 +2093,57 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { return Value; } +static bool isSafeNUWTrunc(llvm::Value *V, llvm::Type *DestTy) { + if (!V || !DestTy || !DestTy->isIntegerTy()) + return false; + + unsigned SrcBits = V->getType()->getIntegerBitWidth(); + unsigned DestBits = DestTy->getIntegerBitWidth(); + + if (DestBits >= SrcBits) + return false; + if (V->getType()->isIntegerTy(1)) + return true; + if (llvm::ZExtInst *Zext = dyn_cast<llvm::ZExtInst>(V)) { + if (Zext->getSrcTy()->isIntegerTy(1) && DestBits == 1) + return true; + } + if (llvm::LoadInst *I = dyn_cast<llvm::LoadInst>(V)) { + if (llvm::MDNode *RangeMD = I->getMetadata(llvm::LLVMContext::MD_range)) { + if (RangeMD->getNumOperands() == 2) { + llvm::ConstantAsMetadata *LowMD = + cast<llvm::ConstantAsMetadata>(RangeMD->getOperand(0)); + llvm::ConstantAsMetadata *HighMD = + cast<llvm::ConstantAsMetadata>(RangeMD->getOperand(1)); + + if (LowMD && HighMD) { + llvm::ConstantInt *LowConst = + dyn_cast<llvm::ConstantInt>(LowMD->getValue()); + llvm::ConstantInt *HighConst = + dyn_cast<llvm::ConstantInt>(HighMD->getValue()); + + if (LowConst && HighConst) { + llvm::APInt HighVal = HighConst->getValue(); + llvm::APInt MaxVal = + llvm::APInt(HighVal.getBitWidth(), 1ULL << DestBits); + + if (HighVal.ule(MaxVal)) { + return true; + } + } + } + } + } + } + + if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(V)) { + llvm::APInt Val = CI->getValue(); + return Val.ule(llvm::APInt::getMaxValue(DestBits)); + } + + return false; +} + /// Converts a scalar value from its load/store type (as returned /// by convertTypeForLoadStore) to its primary IR type (as returned /// by ConvertType). @@ -2111,9 +2162,12 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { } llvm::Type *ResTy = ConvertType(Ty); + bool IsSafe = isSafeNUWTrunc(Value, ResTy); + if (hasBooleanRepresentation(Ty) || Ty->isBitIntType() || - Ty->isExtVectorBoolType()) - return Builder.CreateTrunc(Value, ResTy, "loadedv"); + Ty->isExtVectorBoolType()) { + return Builder.CreateTrunc(Value, ResTy, "loadedv", /*IsNUW*/ IsSafe); + } return Value; } diff --git a/clang/test/C/drs/dr335.c b/clang/test/C/drs/dr335.c index 3ce6ce5bd53ca..8bbd119b88c20 100644 --- a/clang/test/C/drs/dr335.c +++ b/clang/test/C/drs/dr335.c @@ -45,6 +45,6 @@ void dr335(void) { // CHECK-NEXT: %[[CLEAR2:.+]] = and i8 %[[LOAD2]], -2 // CHECK-NEXT: %[[SET:.+]] = or i8 %[[CLEAR2]], %[[ZERO]] // CHECK-NEXT: store i8 %[[SET]], ptr {{.+}}, align 1 - // CHECK-NEXT: {{.+}} = trunc i8 %[[ZERO]] to i1 + // CHECK-NEXT: {{.+}} = trunc nuw i8 %[[ZERO]] to i1 } diff --git a/clang/test/CodeGen/PowerPC/bool_test.c b/clang/test/CodeGen/PowerPC/bool_test.c index d3e7db3c66dad..6b5b4fe5dc202 100644 --- a/clang/test/CodeGen/PowerPC/bool_test.c +++ b/clang/test/CodeGen/PowerPC/bool_test.c @@ -10,7 +10,7 @@ void f(_Bool *x, _Bool *y) { // CHECK-LABEL: define{{.*}} void @f( // CHECK: [[FROMMEM:%.*]] = load i8, ptr % -// CHECK: [[BOOLVAL:%.*]] = trunc i8 [[FROMMEM]] to i1 +// CHECK: [[BOOLVAL:%.*]] = trunc nuw i8 [[FROMMEM]] to i1 // CHECK: [[TOMEM:%.*]] = zext i1 [[BOOLVAL]] to i8 // CHECK: store i8 [[TOMEM]] // CHECK: ret void diff --git a/clang/test/CodeGen/atomic-ops-load.c b/clang/test/CodeGen/atomic-ops-load.c index 778a7ebdc2618..f737f23ad6aea 100644 --- a/clang/test/CodeGen/atomic-ops-load.c +++ b/clang/test/CodeGen/atomic-ops-load.c @@ -4,7 +4,7 @@ extern bool t1; bool test1(void) { // CHECK-LABEL: define{{.*}} i1 @test1 -// CHECK: load atomic i8, ptr @t1 monotonic, align 1, !range ![[$WS_RANGE:[0-9]*]], !noundef !{{[0-9]+}} +// CHECK: load atomic i8, ptr @t1 monotonic, align 1 // CHECK-NEXT: trunc nuw i8 %{{.*}} to i1 // CHECK-NEXT: ret i1 %{{.*}} return __atomic_load_n(&t1, __ATOMIC_RELAXED); diff --git a/clang/test/CodeGenCXX/attr-likelihood-if-branch-weights.cpp b/clang/test/CodeGenCXX/attr-likelihood-if-branch-weights.cpp index a77593f5df738..e502d6582054e 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-if-branch-weights.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-if-branch-weights.cpp @@ -10,7 +10,7 @@ extern bool B(); // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 1 // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2:![0-9]+]], !range [[RNG6:![0-9]+]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 true) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -37,7 +37,7 @@ bool f() { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 1 // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -65,7 +65,7 @@ bool g() { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 1 // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -90,7 +90,7 @@ bool h() { // CHECK-LABEL: @_Z8NullStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] // CHECK: if.then: @@ -113,7 +113,7 @@ void NullStmt() { // CHECK-LABEL: @_Z6IfStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END2:%.*]] // CHECK: if.then: @@ -125,7 +125,7 @@ void NullStmt() { // CHECK-NEXT: br label [[IF_END2]] // CHECK: if.end2: // CHECK-NEXT: [[TMP1:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL3:%.*]] = trunc i8 [[TMP1]] to i1 +// CHECK-NEXT: [[TOBOOL3:%.*]] = trunc nuw i8 [[TMP1]] to i1 // CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_THEN4:%.*]], label [[IF_END8:%.*]] // CHECK: if.then4: // CHECK-NEXT: [[CALL5:%.*]] = call noundef zeroext i1 @_Z1Bv() @@ -152,7 +152,7 @@ void IfStmt() { // CHECK-LABEL: @_Z9WhileStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -166,7 +166,7 @@ void IfStmt() { // CHECK-NEXT: br label [[IF_END]] // CHECK: if.end: // CHECK-NEXT: [[TMP1:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc i8 [[TMP1]] to i1 +// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc nuw i8 [[TMP1]] to i1 // CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END7:%.*]] // CHECK: if.then2: // CHECK-NEXT: br label [[WHILE_COND3:%.*]] @@ -194,7 +194,7 @@ void WhileStmt() { // CHECK-LABEL: @_Z6DoStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -208,7 +208,7 @@ void WhileStmt() { // CHECK-NEXT: br label [[IF_END]] // CHECK: if.end: // CHECK-NEXT: [[TMP1:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc i8 [[TMP1]] to i1 +// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc nuw i8 [[TMP1]] to i1 // CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END7:%.*]] // CHECK: if.then2: // CHECK-NEXT: br label [[DO_BODY3:%.*]] @@ -237,7 +237,7 @@ void DoStmt() { // CHECK-LABEL: @_Z7ForStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] // CHECK: if.then: @@ -251,7 +251,7 @@ void DoStmt() { // CHECK-NEXT: br label [[IF_END]] // CHECK: if.end: // CHECK-NEXT: [[TMP1:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc i8 [[TMP1]] to i1 +// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc nuw i8 [[TMP1]] to i1 // CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END7:%.*]] // CHECK: if.then2: // CHECK-NEXT: br label [[FOR_COND3:%.*]] @@ -278,7 +278,7 @@ void ForStmt() { // CHECK-LABEL: @_Z8GotoStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] // CHECK: if.then: @@ -304,7 +304,7 @@ end:; // CHECK-LABEL: @_Z10ReturnStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] // CHECK: if.then: @@ -327,7 +327,7 @@ void ReturnStmt() { // CHECK-LABEL: @_Z10SwitchStmtv( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: [[TOBOOL:%.*]] = trunc nuw i8 [[TMP0]] to i1 // CHECK-NEXT: [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false) // CHECK-NEXT: br i1 [[TOBOOL_EXPVAL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] // CHECK: if.then: @@ -341,7 +341,7 @@ void ReturnStmt() { // CHECK-NEXT: br label [[IF_END]] // CHECK: if.end: // CHECK-NEXT: [[TMP2:%.*]] = load volatile i8, ptr @b, align 1, !tbaa [[TBAA2]], !range [[RNG6]] -// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc i8 [[TMP2]] to i1 +// CHECK-NEXT: [[TOBOOL1:%.*]] = trunc nuw i8 [[TMP2]] to i1 // CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_ELSE4:%.*]] // CHECK: if.then2: // CHECK-NEXT: [[TMP3:%.*]] = load volatile i32, ptr @i, align 4, !tbaa [[TBAA15]] diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m index 4a3c00c9807a9..51fc33ec29966 100644 --- a/clang/test/CodeGenObjC/arc-ternary-op.m +++ b/clang/test/CodeGenObjC/arc-ternary-op.m @@ -14,7 +14,7 @@ void test0(_Bool cond) { // CHECK-NEXT: store // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[X]]) // CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[COND]] - // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1 + // CHECK-NEXT: [[T1:%.*]] = trunc nuw i8 [[T0]] to i1 // CHECK-NEXT: store i1 false, ptr [[RELCOND]] // CHECK-NEXT: br i1 [[T1]], // CHECK: br label From 7e60e8fed3ff186d1aa85f1292d491eafcc5afbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20G=C3=B3rski?= <jan.a.gor...@wp.pl> Date: Thu, 10 Apr 2025 15:50:05 +0200 Subject: [PATCH 6/6] fixup! Merge branch 'main' into add_range_metadata --- clang/lib/CodeGen/CGExpr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index aadf6a34f8c55..6ae1db749633d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2147,7 +2147,7 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { llvm::Type *ResTy = ConvertType(Ty); bool IsSafe = isSafeNUWTrunc(Value, ResTy); - if (hasBooleanRepresentation(Ty) || Ty->isBitIntType() || + if (Ty->hasBooleanRepresentation() || Ty->isBitIntType() || Ty->isExtVectorBoolType()) { return Builder.CreateTrunc(Value, ResTy, "loadedv", /*IsNUW*/ IsSafe); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits