[clang] [clang][CodeGen] Add range metadata for atomic load of boolean type. #131476 (PR #133546)
Jan Górski via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 10 07:12:53 PDT 2025
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.gorski at 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.gorski at 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.gorski at 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.gorski at 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.gorski at 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.gorski at 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);
}
More information about the cfe-commits
mailing list