[PATCH] D150943: [SimplifyCFG] add nsw on BuildLookuptable LinearMap calculation

Kohei Asano via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 23:19:24 PDT 2023


khei4 added inline comments.


================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6122
+    LinearOffset->getValue().sadd_ov(
+        LinearMultiplier->getValue().smul_ov(MaxIndex, MulSW), AddSW);
     if (!LinearMultiplier->isOne())
----------------
khei4 wrote:
> khei4 wrote:
> > nikic wrote:
> > > I don't think this is sufficient. Let's say we have multiplier 2 and MaxIndex is -1 (that is, full range). Then 2*-1 does not overflow, but there are still plenty of values in the range that do overflow (e.g. INT_MAX).
> > > 
> > > A possible way to properly handle this would be using ConstantRange. I think another possibility is to used ssub_ov for the `Val - PrevVal` calculation above and set NSW based on the overflow flag there.
> > > 
> > > In any case, we need additional tests to cover this.
> > > Let's say we have multiplier 2 and MaxIndex is -1 (that is, full range). Then 2*-1 does not overflow, but there are still plenty of values in the range that do overflow (e.g. INT_MAX).
> > 
> > Yeah, its case matters. Overflowed MaxIndex should be handled. I'll use ConstantRange! 
> > 
> > Also, I'll add a linear map test that uses full range.
> @nikic It seems like I missed [[ https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/SimplifyCFG.cpp#L6411-L6414 | Max/MinIndex is signed sense ]].
> I think the tests we need are unsigned results with signed-overflowed/underflowed values
> 
>  It seems like I missed Max/MinIndex in a signed sense.

I mean we don't need to worry about signed-over/underflow checks with falsy unsigned sense Max/MinIndex.

And I guess [[ https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll#L1695-L1712 | this ]] is index full range tests.
(from above URL)

```
define i32 @signed_overflow1(i8 %n) {
; CHECK-LABEL: @signed_overflow1(
; CHECK-NEXT:  start:
; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2
; CHECK-NEXT:    [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2
; CHECK-NEXT:    [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3
; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow1, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]]
; CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4
; CHECK-NEXT:    ret i32 [[SWITCH_LOAD]]
;
start:
  %trunc = trunc i8 %n to i2
  switch i2 %trunc, label %bb1 [
  i2 0, label %bb6
  i2 1, label %bb3
  i2 -2, label %bb4
  i2 -1, label %bb5
  ]

bb1:                                              ; preds = %start
  unreachable

bb3:                                              ; preds = %start
  br label %bb6

bb4:                                              ; preds = %start
  br label %bb6

bb5:                                              ; preds = %start
  br label %bb6

bb6:                                              ; preds = %start, %bb3, %bb4, %bb5
  %.sroa.0.0 = phi i32 [ 4444, %bb5 ], [ 3333, %bb4 ], [ 2222, %bb3 ], [ 1111, %start ]
  ret i32 %.sroa.0.0
}

```


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150943/new/

https://reviews.llvm.org/D150943



More information about the llvm-commits mailing list