[llvm] Handle GEPs with negative offset and 'nuw' attribute (PR #117147)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 04:07:11 PST 2024


https://github.com/pkarveti created https://github.com/llvm/llvm-project/pull/117147

This commit fixes incorrect DAG replacement when the 'nuw' attribute
 is added to inbound GEPs with a negative offset.

- If the offset is negative and the 'nuw' attribute is present, the 'nuw' flag is set to false.



>From d8595da4e31b1c12f71c3046160a53eb6eda88df Mon Sep 17 00:00:00 2001
From: pavani karveti <quic_pkarveti at quicinc.com>
Date: Thu, 21 Nov 2024 03:35:07 -0800
Subject: [PATCH] Handle GEPs with negative offset and 'nuw' attribute

This commit fixes incorrect DAG replacement when
the 'nuw' attribute is added to inbounds GEPs
with a negative offset.

- If the offset is negative and the 'nuw' attribute
is present, the 'nuw' flag is set to false.

Change-Id: I4c72171545ba3b98a20473eefdb29bab10505bed
---
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  11 +-
 llvm/test/CodeGen/Hexagon/gep_nuw.ll          | 228 ++++++++++++++++++
 2 files changed, 236 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/Hexagon/gep_nuw.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 25213f587116d5..2d355f3d74cfb8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4363,10 +4363,15 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
         // In an inbounds GEP with an offset that is nonnegative even when
         // interpreted as signed, assume there is no unsigned overflow.
         SDNodeFlags Flags;
-        if (NW.hasNoUnsignedWrap() ||
-            (Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
+        if (NW.hasNoUnsignedWrap()) {
+          if (!Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()) {
+            Flags.setNoUnsignedWrap(false);
+          } else {
+            Flags.setNoUnsignedWrap(true);
+          }
+        } else if (Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()) {
           Flags.setNoUnsignedWrap(true);
-
+        }
         OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
 
         N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal, Flags);
diff --git a/llvm/test/CodeGen/Hexagon/gep_nuw.ll b/llvm/test/CodeGen/Hexagon/gep_nuw.ll
new file mode 100644
index 00000000000000..9c0b4c52bb4cba
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/gep_nuw.ll
@@ -0,0 +1,228 @@
+;RUN: llc  -stop-after="hexagon-isel"  < %s | FileCheck %s
+
+;CHECK: %54:intregs = L2_loadrub_io %27, -1
+target triple = "hexagon"
+
+ at global = external dso_local local_unnamed_addr global ptr, align 4
+
+; Function Attrs: nofree norecurse nosync nounwind memory(read, argmem: readwrite, inaccessiblemem: none)
+define dso_local void @quux(i32 noundef %arg, ptr nocapture noundef readonly %arg1, ptr nocapture noundef writeonly %arg2, i32 noundef %arg3) local_unnamed_addr #0 {
+bb:
+  %getelementptr = getelementptr inbounds nuw i8, ptr %arg1, i32 29
+  %load = load i8, ptr %getelementptr, align 1, !tbaa !3
+  %icmp = icmp eq i8 %load, 3
+  br i1 %icmp, label %bb4, label %bb170
+
+bb4:                                              ; preds = %bb
+  %load5 = load ptr, ptr @global, align 4, !tbaa !9
+  %getelementptr6 = getelementptr inbounds nuw i8, ptr %arg1, i32 4
+  %load7 = load ptr, ptr %getelementptr6, align 4, !tbaa !10
+  %getelementptr8 = getelementptr inbounds nuw i8, ptr %load7, i32 8
+  %load9 = load i32, ptr %getelementptr8, align 4, !tbaa !11
+  %getelementptr10 = getelementptr inbounds nuw i8, ptr %load5, i32 %load9
+  %getelementptr11 = getelementptr inbounds i8, ptr %getelementptr10, i32 -1
+  %sub = sub i32 0, %arg3
+  %getelementptr12 = getelementptr inbounds i8, ptr %getelementptr10, i32 %sub
+  %getelementptr13 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 4
+  %load14 = load i8, ptr %getelementptr13, align 1, !tbaa !14
+  %zext = zext i8 %load14 to i32
+  %getelementptr15 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 2
+  %load16 = load i8, ptr %getelementptr15, align 1, !tbaa !14
+  %zext17 = zext i8 %load16 to i32
+  %sub18 = sub nsw i32 %zext, %zext17
+  %shl = shl i32 %arg3, 2
+  %getelementptr19 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %shl
+  %load20 = load i8, ptr %getelementptr19, align 1, !tbaa !14
+  %zext21 = zext i8 %load20 to i32
+  %shl22 = shl i32 %arg3, 1
+  %getelementptr23 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %shl22
+  %load24 = load i8, ptr %getelementptr23, align 1, !tbaa !14
+  %zext25 = zext i8 %load24 to i32
+  %sub26 = sub nsw i32 %zext21, %zext25
+  %getelementptr27 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 5
+  %load28 = load i8, ptr %getelementptr27, align 1, !tbaa !14
+  %zext29 = zext i8 %load28 to i32
+  %getelementptr30 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 1
+  %load31 = load i8, ptr %getelementptr30, align 1, !tbaa !14
+  %zext32 = zext i8 %load31 to i32
+  %sub33 = sub nsw i32 %zext29, %zext32
+  %shl34 = shl nsw i32 %sub33, 1
+  %add = add nsw i32 %shl34, %sub18
+  %mul = mul i32 %arg3, 5
+  %getelementptr35 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %mul
+  %load36 = load i8, ptr %getelementptr35, align 1, !tbaa !14
+  %zext37 = zext i8 %load36 to i32
+  %getelementptr38 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %arg3
+  %load39 = load i8, ptr %getelementptr38, align 1, !tbaa !14
+  %zext40 = zext i8 %load39 to i32
+  %sub41 = sub nsw i32 %zext37, %zext40
+  %shl42 = shl nsw i32 %sub41, 1
+  %add43 = add nsw i32 %shl42, %sub26
+  %getelementptr44 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 6
+  %load45 = load i8, ptr %getelementptr44, align 1, !tbaa !14
+  %zext46 = zext i8 %load45 to i32
+  %load47 = load i8, ptr %getelementptr12, align 1, !tbaa !14
+  %zext48 = zext i8 %load47 to i32
+  %sub49 = sub nsw i32 %zext46, %zext48
+  %mul50 = mul nsw i32 %sub49, 3
+  %add51 = add nsw i32 %mul50, %add
+  %mul53 = mul i32 %arg3, 6
+  %getelementptr54 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %mul53
+  %load55 = load i8, ptr %getelementptr54, align 1, !tbaa !14
+  %zext56 = zext i8 %load55 to i32
+  %load57 = load i8, ptr %getelementptr11, align 1, !tbaa !14
+  %zext58 = zext i8 %load57 to i32
+  %sub59 = sub nsw i32 %zext56, %zext58
+  %mul60 = mul nsw i32 %sub59, 3
+  %add61 = add nsw i32 %mul60, %add43
+  %getelementptr62 = getelementptr inbounds i8, ptr %getelementptr12, i32 7
+  %load63 = load i8, ptr %getelementptr62, align 1, !tbaa !14
+  %zext64 = zext i8 %load63 to i32
+  %getelementptr65 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 -1
+  %load66 = load i8, ptr %getelementptr65, align 1, !tbaa !14
+  %zext67 = zext i8 %load66 to i32
+  %sub68 = sub nsw i32 %zext64, %zext67
+  %shl69 = shl nsw i32 %sub68, 2
+  %add70 = add nsw i32 %shl69, %add51
+  %mul71 = mul i32 %arg3, 7
+  %getelementptr72 = getelementptr inbounds i8, ptr %getelementptr11, i32 %mul71
+  %load73 = load i8, ptr %getelementptr72, align 1, !tbaa !14
+  %zext74 = zext i8 %load73 to i32
+  %sub75 = sub i32 0, %arg3
+  %getelementptr76 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %sub75
+  %load77 = load i8, ptr %getelementptr76, align 1, !tbaa !14
+  %zext78 = zext i8 %load77 to i32
+  %sub79 = sub nsw i32 %zext74, %zext78
+  %shl80 = shl nsw i32 %sub79, 2
+  %add81 = add nsw i32 %shl80, %add61
+  %add82 = add nuw nsw i32 %zext74, %zext64
+  %shl83 = shl nuw nsw i32 %add82, 4
+  %mul84 = mul nsw i32 %add70, 17
+  %add85 = add nsw i32 %mul84, 16
+  %ashr = ashr i32 %add85, 5
+  %mul86 = mul nsw i32 %add81, 17
+  %add87 = add nsw i32 %mul86, 16
+  %ashr88 = ashr i32 %add87, 5
+  %add89 = add nuw nsw i32 %shl83, 16
+  %mul90 = mul nsw i32 %ashr, -3
+  %shl91 = shl nsw i32 %ashr, 1
+  %mul92 = mul nsw i32 %ashr, 3
+  %shl93 = shl nsw i32 %ashr, 2
+  %shl94 = shl nsw i32 %ashr, 1
+  br label %bb95
+
+bb95:                                             ; preds = %bb95, %bb4
+  %phi = phi ptr [ %arg2, %bb4 ], [ %getelementptr167, %bb95 ]
+  %phi96 = phi i32 [ 0, %bb4 ], [ %add168, %bb95 ]
+  %add97 = add nsw i32 %phi96, -3
+  %mul98 = mul nsw i32 %add97, %ashr88
+  %add99 = add i32 %add89, %mul98
+  %add100 = add i32 %add99, %mul90
+  %ashr101 = ashr i32 %add100, 5
+  %and = and i32 %add100, 8192
+  %icmp102 = icmp eq i32 %and, 0
+  %icmp103 = icmp slt i32 %ashr101, 0
+  %select = select i1 %icmp103, i32 0, i32 255
+  %select104 = select i1 %icmp102, i32 %ashr101, i32 %select
+  %trunc = trunc i32 %select104 to i8
+  store i8 %trunc, ptr %phi, align 1, !tbaa !14
+  %getelementptr105 = getelementptr inbounds nuw i8, ptr %phi, i32 1
+  %sub106 = sub i32 %add99, %shl94
+  %ashr107 = ashr i32 %sub106, 5
+  %and108 = and i32 %sub106, 8192
+  %icmp109 = icmp eq i32 %and108, 0
+  %icmp110 = icmp slt i32 %ashr107, 0
+  %select111 = select i1 %icmp110, i32 0, i32 255
+  %select112 = select i1 %icmp109, i32 %ashr107, i32 %select111
+  %trunc113 = trunc i32 %select112 to i8
+  store i8 %trunc113, ptr %getelementptr105, align 1, !tbaa !14
+  %getelementptr114 = getelementptr inbounds nuw i8, ptr %phi, i32 2
+  %sub115 = sub i32 %add99, %ashr
+  %ashr116 = ashr i32 %sub115, 5
+  %and117 = and i32 %sub115, 8192
+  %icmp118 = icmp eq i32 %and117, 0
+  %icmp119 = icmp slt i32 %ashr116, 0
+  %select120 = select i1 %icmp119, i32 0, i32 255
+  %select121 = select i1 %icmp118, i32 %ashr116, i32 %select120
+  %trunc122 = trunc i32 %select121 to i8
+  store i8 %trunc122, ptr %getelementptr114, align 1, !tbaa !14
+  %getelementptr123 = getelementptr inbounds nuw i8, ptr %phi, i32 3
+  %ashr124 = ashr i32 %add99, 5
+  %and125 = and i32 %add99, 8192
+  %icmp126 = icmp eq i32 %and125, 0
+  %icmp127 = icmp slt i32 %ashr124, 0
+  %select128 = select i1 %icmp127, i32 0, i32 255
+  %select129 = select i1 %icmp126, i32 %ashr124, i32 %select128
+  %trunc130 = trunc i32 %select129 to i8
+  store i8 %trunc130, ptr %getelementptr123, align 1, !tbaa !14
+  %getelementptr131 = getelementptr inbounds nuw i8, ptr %phi, i32 4
+  %add132 = add i32 %add99, %ashr
+  %ashr133 = ashr i32 %add132, 5
+  %and134 = and i32 %add132, 8192
+  %icmp135 = icmp eq i32 %and134, 0
+  %icmp136 = icmp slt i32 %ashr133, 0
+  %select137 = select i1 %icmp136, i32 0, i32 255
+  %select138 = select i1 %icmp135, i32 %ashr133, i32 %select137
+  %trunc139 = trunc i32 %select138 to i8
+  store i8 %trunc139, ptr %getelementptr131, align 1, !tbaa !14
+  %getelementptr140 = getelementptr inbounds nuw i8, ptr %phi, i32 5
+  %add141 = add i32 %add99, %shl91
+  %ashr142 = ashr i32 %add141, 5
+  %and143 = and i32 %add141, 8192
+  %icmp144 = icmp eq i32 %and143, 0
+  %icmp145 = icmp slt i32 %ashr142, 0
+  %select146 = select i1 %icmp145, i32 0, i32 255
+  %select147 = select i1 %icmp144, i32 %ashr142, i32 %select146
+  %trunc148 = trunc i32 %select147 to i8
+  store i8 %trunc148, ptr %getelementptr140, align 1, !tbaa !14
+  %getelementptr149 = getelementptr inbounds nuw i8, ptr %phi, i32 6
+  %add150 = add i32 %add99, %mul92
+  %ashr151 = ashr i32 %add150, 5
+  %and152 = and i32 %add150, 8192
+  %icmp153 = icmp eq i32 %and152, 0
+  %icmp154 = icmp slt i32 %ashr151, 0
+  %select155 = select i1 %icmp154, i32 0, i32 255
+  %select156 = select i1 %icmp153, i32 %ashr151, i32 %select155
+  %trunc157 = trunc i32 %select156 to i8
+  store i8 %trunc157, ptr %getelementptr149, align 1, !tbaa !14
+  %getelementptr158 = getelementptr inbounds nuw i8, ptr %phi, i32 7
+  %add159 = add i32 %add99, %shl93
+  %ashr160 = ashr i32 %add159, 5
+  %and161 = and i32 %add159, 8192
+  %icmp162 = icmp eq i32 %and161, 0
+  %icmp163 = icmp slt i32 %ashr160, 0
+  %select164 = select i1 %icmp163, i32 0, i32 255
+  %select165 = select i1 %icmp162, i32 %ashr160, i32 %select164
+  %trunc166 = trunc i32 %select165 to i8
+  store i8 %trunc166, ptr %getelementptr158, align 1, !tbaa !14
+  %getelementptr167 = getelementptr inbounds nuw i8, ptr %phi, i32 8
+  %add168 = add nuw nsw i32 %phi96, 1
+  %icmp169 = icmp eq i32 %add168, 8
+  br i1 %icmp169, label %bb170, label %bb95, !llvm.loop !15
+
+bb170:                                            ; preds = %bb95, %bb
+  ret void
+}
+
+attributes #0 = { nofree norecurse nosync nounwind memory(read, argmem: readwrite, inaccessiblemem: none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv68" "target-features"="+v68,-long-calls" }
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{!"QuIC LLVM Hexagon Clang version 8.9 Engineering Release: hexagon-clang-89"}
+!3 = !{!4, !6, i64 29}
+!4 = !{!"MB_STRUCT", !5, i64 0, !5, i64 4, !5, i64 8, !8, i64 12, !8, i64 16, !8, i64 20, !8, i64 24, !6, i64 28, !6, i64 29, !5, i64 32}
+!5 = !{!"any pointer", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!"int", !6, i64 0}
+!9 = !{!5, !5, i64 0}
+!10 = !{!4, !5, i64 4}
+!11 = !{!12, !8, i64 8}
+!12 = !{!"BLOCK_STRUCT_CHROM", !5, i64 0, !5, i64 4, !8, i64 8, !13, i64 12, !13, i64 14, !6, i64 16, !6, i64 17, !6, i64 18, !6, i64 19}
+!13 = !{!"short", !6, i64 0}
+!14 = !{!6, !6, i64 0}
+!15 = distinct !{!15, !16}
+!16 = !{!"llvm.loop.mustprogress"}



More information about the llvm-commits mailing list