[llvm] [InstCombine] Detect uadd with overflow idiom (PR #140178)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 2 16:36:12 PDT 2025
================
@@ -147,3 +147,76 @@ define { <2 x i32>, <2 x i1> } @fold_simple_splat_constant_with_or_fail(<2 x i32
%b = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> <i32 30, i32 30>)
ret { <2 x i32>, <2 x i1> } %b
}
+
+define i32 @uadd_with_zext(i32 %x, i32 %y) {
+; CHECK-LABEL: @uadd_with_zext(
+; CHECK-NEXT: [[UADD:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i32, i1 } [[UADD]], 1
+; CHECK-NEXT: [[COND:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT: ret i32 [[COND]]
+;
+ %conv = zext i32 %x to i64
+ %conv1 = zext i32 %y to i64
+ %add = add i64 %conv, %conv1
+ %cmp = icmp ugt i64 %add, 4294967295
+ %cond = zext i1 %cmp to i32
+ ret i32 %cond
+}
+
+define i32 @uadd_with_zext_use_and(i32 %x, i32 %y) {
+; CHECK-LABEL: @uadd_with_zext_use_and(
+; CHECK-NEXT: [[UADD:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
+; CHECK-NEXT: [[UADD_VALUE:%.*]] = extractvalue { i32, i1 } [[UADD]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[UADD_VALUE]], 65536
+; CHECK-NEXT: [[AND:%.*]] = zext nneg i32 [[TMP1]] to i64
+; CHECK-NEXT: call void @usei64(i64 [[AND]])
+; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i32, i1 } [[UADD]], 1
+; CHECK-NEXT: [[COND:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT: ret i32 [[COND]]
+;
+ %conv = zext i32 %x to i64
+ %conv1 = zext i32 %y to i64
+ %add = add i64 %conv, %conv1
+ %and = and i64 %add, 65536
----------------
topperc wrote:
This is a bit of an odd choice of constant. 65536 has a single bit set. Something closer to 4294967295 would match the intent of the check in the code.
https://github.com/llvm/llvm-project/pull/140178
More information about the llvm-commits
mailing list