llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Craig Topper (topperc)

<details>
<summary>Changes</summary>

The ctlz will produce a value in the range [1..bitwidth]. It can't produce 0. 
This means the subtract of 1 will not have unsigned wrap.

It also has no signed wrap, but the optimizer can figure that out on its own.

It's very likely InstCombine will just drop the NUW when it canonicalizes to 
Add, but maybe it will be helpful in some case.

---
Full diff: https://github.com/llvm/llvm-project/pull/174010.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+2-1) 
- (modified) clang/test/CodeGen/builtin_clrsb.c (+2-2) 


``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d3abf6d2a1f2d..bd1ef267a7f22 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3292,7 +3292,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
     Value *Inverse = Builder.CreateNot(ArgValue, "not");
     Value *Tmp = Builder.CreateSelect(IsNeg, Inverse, ArgValue);
     Value *Ctlz = Builder.CreateCall(F, {Tmp, Builder.getFalse()});
-    Value *Result = Builder.CreateSub(Ctlz, llvm::ConstantInt::get(ArgType, 
1));
+    Value *Result =
+        Builder.CreateNUWSub(Ctlz, llvm::ConstantInt::get(ArgType, 1));
     Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
                                    "cast");
     return RValue::get(Result);
diff --git a/clang/test/CodeGen/builtin_clrsb.c 
b/clang/test/CodeGen/builtin_clrsb.c
index c51777ed1222c..1f6c93ff4c570 100644
--- a/clang/test/CodeGen/builtin_clrsb.c
+++ b/clang/test/CodeGen/builtin_clrsb.c
@@ -6,7 +6,7 @@ int test__builtin_clrsb(int x) {
 // CHECK-NEXT: [[INV:%.*]] = xor i32 [[X]], -1
 // CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[INV]], i32 [[X]]
 // CHECK-NEXT: [[CTLZ:%.*]] = call i32 @llvm.ctlz.i32(i32 [[SEL]], i1 false)
-// CHECK-NEXT: [[SUB:%.*]] = sub i32 [[CTLZ]], 1
+// CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[CTLZ]], 1
   return __builtin_clrsb(x);
 }
 
@@ -16,7 +16,7 @@ int test__builtin_clrsbll(long long x) {
 // CHECK-NEXT: [[INV:%.*]] = xor i64 [[X]], -1
 // CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[INV]], i64 [[X]]
 // CHECK-NEXT: [[CTLZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[SEL]], i1 false)
-// CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CTLZ]], 1
+// CHECK-NEXT: [[SUB:%.*]] = sub nuw i64 [[CTLZ]], 1
 // CHECK-NEXT: trunc i64 [[SUB]] to i32
   return __builtin_clrsbll(x);
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/174010
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to