From 25b4315f44767f406b5ba08d8e2147605e29ad96 Mon Sep 17 00:00:00 2001 From: Vladimir Radosavljevic Date: Tue, 18 Jun 2024 10:55:05 +0200 Subject: [PATCH 1/2] [CGP] Add pre-commit test for Fix matching of uadd overflow Add tests where uadd overflow intrinsic is matched for: `Add = add A,(uint64_t)-1; Cmp = icmp ne A, 0` instead of: `Add = add A,-1; Cmp = icmp ne A, 0` where -1 is represented in 256 bits. Signed-off-by: Vladimir Radosavljevic --- .../EraVM/cgp-uadd-overflow-wrong-match.ll | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll diff --git a/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll b/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll new file mode 100644 index 000000000000..b8d4d6196ad6 --- /dev/null +++ b/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll @@ -0,0 +1,55 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -codegenprepare --cgp-verify-bfi-updates=false -S < %s | FileCheck %s +; Verification of BFI updates is disabled because of https://github.com/llvm/llvm-project/issues/64197 + +target datalayout = "E-p:256:256-i256:256:256-S32-a:256:256" +target triple = "eravm" + +define i256 @dont_match(i256 %a) { +; CHECK-LABEL: define i256 @dont_match +; CHECK-SAME: (i256 [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 [[A]], i256 18446744073709551615) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i256, i1 } [[TMP0]], 0 +; CHECK-NEXT: [[OV:%.*]] = extractvalue { i256, i1 } [[TMP0]], 1 +; CHECK-NEXT: br i1 [[OV]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: ret i256 0 +; CHECK: else: +; CHECK-NEXT: ret i256 [[MATH]] +; +entry: + %add = add i256 %a, 18446744073709551615 + %cmp = icmp ne i256 %a, 0 + br i1 %cmp, label %then, label %else + +then: + ret i256 0 + +else: + ret i256 %add +} + +define i256 @match(i256 %a) { +; CHECK-LABEL: define i256 @match +; CHECK-SAME: (i256 [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ADD:%.*]] = add i256 [[A]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i256 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: ret i256 0 +; CHECK: else: +; CHECK-NEXT: ret i256 [[ADD]] +; +entry: + %add = add i256 %a, -1 + %cmp = icmp ne i256 %a, 0 + br i1 %cmp, label %then, label %else + +then: + ret i256 0 + +else: + ret i256 %add +} From 098d48190b4244b6b8c5910925a6a0bd98dee0f5 Mon Sep 17 00:00:00 2001 From: Vladimir Radosavljevic Date: Tue, 18 Jun 2024 11:05:48 +0200 Subject: [PATCH 2/2] [CGP] Fix matching of uadd overflow This patch fixes the issue where uadd overflow intrinsic is matched for: `Add = add A,(uint64_t)-1; Cmp = icmp ne A, 0` instead of: `Add = add A,-1; Cmp = icmp ne A, 0` where -1 is represented in 256 bits. PR: #626 Signed-off-by: Vladimir Radosavljevic --- llvm/lib/CodeGen/CodeGenPrepare.cpp | 4 +++- .../EraVM/cgp-uadd-overflow-wrong-match.ll | 18 +++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index b2e99ecfb48c..92749b204c35 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -1584,7 +1584,9 @@ static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, if (Pred == ICmpInst::ICMP_EQ && match(B, m_AllOnes())) B = ConstantInt::get(B->getType(), 1); else if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) - B = ConstantInt::get(B->getType(), -1); + // EraVM local begin + B = ConstantInt::get(B->getType(), -1, true); + // EraVM local end else return false; diff --git a/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll b/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll index b8d4d6196ad6..919038d95932 100644 --- a/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll +++ b/llvm/test/CodeGen/EraVM/cgp-uadd-overflow-wrong-match.ll @@ -9,14 +9,13 @@ define i256 @dont_match(i256 %a) { ; CHECK-LABEL: define i256 @dont_match ; CHECK-SAME: (i256 [[A:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 [[A]], i256 18446744073709551615) -; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i256, i1 } [[TMP0]], 0 -; CHECK-NEXT: [[OV:%.*]] = extractvalue { i256, i1 } [[TMP0]], 1 -; CHECK-NEXT: br i1 [[OV]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK-NEXT: [[ADD:%.*]] = add i256 [[A]], 18446744073709551615 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i256 [[A]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] ; CHECK: then: ; CHECK-NEXT: ret i256 0 ; CHECK: else: -; CHECK-NEXT: ret i256 [[MATH]] +; CHECK-NEXT: ret i256 [[ADD]] ; entry: %add = add i256 %a, 18446744073709551615 @@ -34,13 +33,14 @@ define i256 @match(i256 %a) { ; CHECK-LABEL: define i256 @match ; CHECK-SAME: (i256 [[A:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[ADD:%.*]] = add i256 [[A]], -1 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i256 [[A]], 0 -; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 [[A]], i256 -1) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i256, i1 } [[TMP0]], 0 +; CHECK-NEXT: [[OV:%.*]] = extractvalue { i256, i1 } [[TMP0]], 1 +; CHECK-NEXT: br i1 [[OV]], label [[THEN:%.*]], label [[ELSE:%.*]] ; CHECK: then: ; CHECK-NEXT: ret i256 0 ; CHECK: else: -; CHECK-NEXT: ret i256 [[ADD]] +; CHECK-NEXT: ret i256 [[MATH]] ; entry: %add = add i256 %a, -1