[PATCH] D21246: [InstCombine] Add rule to fold away trunc of partial load

Anna Thomas via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 17 11:07:01 PDT 2016


anna added inline comments.

================
Comment at: lib/Transforms/InstCombine/InstCombineCasts.cpp:588
@@ +587,3 @@
+    if (Value *AvailableVal = FindAvailableLoadedValue(
+            LI, LI->getParent(), BBI, DefMaxInstsToScan,
+            /* AA */ nullptr, /* AATags */ nullptr, DestTy))
----------------
sanjoy wrote:
> anna wrote:
> > sanjoy wrote:
> > > Here if we have:
> > > 
> > > ```
> > > store i64 %x to %ptr
> > > %val = load i64* %ptr
> > > %val.tr = trunc i64 %val to i32
> > > ```
> > > 
> > > won't we have a type mismatch and try to replace `%val.tr` with `%x`?
> > We won't replace `%val.tr` with `%x` since the `DestTy` is `i32`. We do the check in  `FindAvailableLoadedValue (LI: %val,.., DestTy: i32)` that `i64` is `BitorNoopPointerCastable` to the PartialType `i32`. 
> > I've added this test case as well now. 
> I was thinking of the case where the first check, i.e.
> 
> ```
>       if (AreEquivalentAddressValues(LoadPtr, StrippedPtr) &&
>           CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
> ```
> 
> or
> 
> ```
>       if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
>           CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
>                                                AccessTy, DL)) {
> ```
> 
> would fire and you'd return a wider value.  So the test case has to be
> 
> ```
> define i1 @trunc_different_size_load(i32 * align 4 %a) {
>   store i32 0, i32 *%a, align 4
>   %wide.load = load i32, i32* %a, align 4
>   %lowhalf = trunc i32 %wide.load to i8
>   call void @consume(i8 %lowhalf)
>   %cmp.2 = icmp ult i32 %wide.load, 256
>   ret i1 %cmp.2
> ; CHECK-LABEL: @trunc_different_size_load
> ; CHECK: %lowhalf = trunc i32 %wide.load to i8
> }
> ```
> 
I see your point about the widening and the mismatch of types. The reason the firing of the first check did not trigger any failures was because a prior instcombine rule (I think it is combineLoadStore which calls `FindAvailableLoad` as well) already removes the trunc. So with or without this trunc rule in instcombine, opt with -instcombine changes the above test case to:
```
define i1 @trunc_different_size_loads(i32* align 4 %a) {
  store i32 0, i32* %a, align 4
  call void @consume(i8 0)
  ret i1 false
}
```
Also verified the value is correctly truncated, say in this case:
```
  store i32 257, i32* %a, align 4
  call void @consume(i8 1)
  ret i1 false
```

That said, I agree we should not be relying on a certain ordering of instcombine rules for this, since there would be a type mismatch in absence of load store instcombine rules.
Will make the change. Thanks :)


http://reviews.llvm.org/D21246





More information about the llvm-commits mailing list